With this commit, ServerCodecConfigurer is now exposed as a bean in
order to be provided to DefaultServerWebExchange via
WebHttpHandlerBuilder and HttpWebHandlerAdapter. This allows
DefaultServerWebExchange to get configured codecs for reading form or
multipart requests.
Issue: SPR-14546
This commit changes the handling of 4xx/5xx status codes in the
WebClient to the following simple rule: if there is no way for the user
to get the response status code, then a WebClientException is returned.
If there is a way to get to the status code, then we do not return an
exception.
Issue: SPR-15486
This commit renames `WebClient.ResponseSpec.bodyToEntity` to `toEntity`
and similarly renames `WebClient.ResponseSpec.bodyToEntityList` to
`toEntityList`. In both cases, the `body` prefix was dropped because the
return value contains more than the body.
Issue: SPR-15486
This commit renames the `body(Object)` on ServerResponse to
`syncBody(Object)`. The reason for this is that the original method
name clashed with the `body(Publisher)` method in the Kotlin extension.
The new name nicely reflects the synchronous nature of the method,
making it less appealing than the `Publisher`-based `body` method.
Issue: SPR-15467
This method introduces a new body(Object) to ServerResponse, a shortcut
to body(BodyInserters.fromObject(Object)).
Note that in the implementation of the method, an `instanceof` check is
performed to make sure that the passed argument is not a `Publisher`,
as users should call `body(Publisher, Class)` for sending a reactive
type.
This Publisher-check is also done in the `WebClient`, for the same
reasons.
Issue: SPR-15461
Without this change it was necessary to call getPathRemaining and
then chop up the path and make a call to matchAndExtract to get the
bound variables for the path part that matched. With this change
this is all done in the call to getPathRemaining which returns
an object holding the remaining path and the bound variables.
Issue: SPR-15419
This commit changes the `HandlerStrategies` and `ExchangeStrategies`
builders to use the `CodecConfigurer` for configuring Decoder|Encoder
and HttpMessage[Reader|Writer]. Other classes that use `CodecConfigurer`
have also been changed to reflect the refactoring to interfaces.
This commit also removes the ExchangeStrategies methods that take an
application context, as it was too naive approach to simply look up
every message reader and writer in the context.
Issue: SPR-15415, SPR-15435
This commit changes the `HandlerStrategies` builder to use
`ServerCodecConfigurer` for configuring Decoder|Encoder and
HttpMessage[Reader|Writer]. Note that the configurer is not exposed
directly, but wrapped so that `HandlerStrategies` can keep on returning
`this` for a proper builder pattern.
This commit also removes the HandlerStrategies methods that take an
application context, as it was too naive approach to simply look up
every message reader and writer in the context.
Issue: SPR-15415
- Renamed `defaultCodec` to `defaultCodecs`, and `customCodec` to
`customCodecs`
- Added `@Override` annotations where necessary
- Fixed non-parameterized usage for parameterized types.
This commit makes CodecException handling consistent between functional
and annotation-based APIs. It now returns by default 4xx status code
for decoding error and 5xx for encoding error + print the error reason
in logs without the full stack trace in both variants.
Issue: SPR-15355
The java.util.Optional wrapper should not affect the support for
"request param" arguments with or without the annotation as it
works on the Spring MVC side.
This commit uses the newly introduced
`PathPattern.getPathRemaining(String)` in the functional web framework.
With this change, all path predicates can be used for nested router
functions, so the `pathPrefix` predicate is no longer required and has
been removed.
Issue: SPR-15336
This commit introduces support for the server-side methods on
HttpMessageReader and HttpMessageWriter. It does so by introducing an
Optional ServerHttpRequest in BodyInserter.Context, and an Optional
ServerHttpResponse in BodyExtractor.Context. On the client-side, these
optionals return Optional.empty(); on the server-side, they return the
respective server-side messages.
Issue: SPR-15370
This change allows the functional WebFlux API to support natively
reactive types and also makes it possible for View implementations to
disable async attributes resolution if they want for example take
advantage of stream rendering.
It also makes AbstractView#getModelAttributes() asynchronous.
Issue: SPR-15368
Replace the overloaded "retrieve" methods with a single retrieve() +
ResponseSpec exposing shortcut methods (bodyToMono, bodyToFlux)
mirroring the ClientResponse shortcuts it delegates to.
Unlike exchange() however with retrieve() there is no access to other
parts of ClientResponse so ResponseSpec exposes additional shortcuts
for obtain ResponseEntity<T> or ResponseEntity<List<T>>.
Issue: SPR-15294
This commit makes a change to WebClient in oder to facilitate getting
the response body as a `Mono<Object>` or `Flux<Object>` without having
to deal with `ClientResponse`.
Specifically, this commit:
- Adds `RequestHeaderSpec.retrieve` methods, next to `exchange`, that
return the response body (and not a `ClientResponse`). Two convenience
methods return the response body as `Mono` or `Flux`.
- Adds ClientResponse.toRequestEntity to convert the ClientResponse
into a RequestEntity.
Issue: SPR-15294
The ServerCodecConfigurer is now passed all the way into the
RequestMappingHandlerAdapter which automatically enables the same
defaults even without the Java config and provides extra flexibility
in passing message codec configuration for the future.
This commit makes changes to WebClient and WebTestClient in oder to
limit setting the body according to HTTP method and also to facilitate
providing the request body as Object.
Specifically, this commit:
- Moves methods that operate on the request body to a RequestBodySpec
in both WebClient and WebTestClient, and rename them to `body`.
These methods now just *set* the body, without performing
an exchange (which now requires an explicit exchange call).
- Parameterizes UriSpec in both WebClient and WebTestClient, so that
it returns either a RequestHeadersSpec or a RequestBodySpec.
Issue: SPR-15394
Extract controller method caches including associated code and
discovery of @ControllerAdvice components into a separate, package
private helper class (ControllerMethodResolver).
This commit folds ServerHttpMessage[Reader|Writer] into its parent
HttpMessage[Reader|Writer] with the server methods pre-implemented
by default to be simple pass-through delegates.
This commit changes `ResourceTransformerSupport` to look for the
`ResourceUrlProvider` in the current request if none is configured on
the resource transformer itself.
Issue: SPR-15369
Prior to this commit, the `VersionResourceResolver` implementations of
`resolveUrlPathInternal` would delegate to the resolver chain but would
never use the give result if the current request didn't match a
configured version strategy pattern.
This is a problem if the resolver supposed to resolve the resource path
is configured after a `VersionResourceResolver` in the resolver chain;
this means that other resolver never gets to participate in the result
of the chain.
Issue: SPR-15372
Includes a new overloaded ModelAndView constructor with an HttpStatus argument, as well as a HandlerMethodArgumentResolverSupport refactoring (revised checkParameterType signature, actually implementing the HandlerMethodArgumentResolver interface).
Issue: SPR-15199
Follow-up to:
3d68c496f1
StringDecoder can be created in text-only vs "*/*" mode which in turn
allows a more intuitive order of client side decoders, e.g. SSE does
not have to be ahead of StringDecoder.
The commit also explicitly disables String from the supported types in
Jackson2Decoder leaving it to the StringDecoder in "*/*" mode which
comes after. This does not change the current arrangement since the
the StringDecoder ahead having "*/*" picks up JSON content just the
same.
From a broader perspective this change allows any decoder to deal with
String if it wants to after examining the content type be it the SSE
or another, custom decoder. For Jackson there is very little value in
decoding to String which works only if the output contains a single
JSON string but will fail to parse anything else (JSON object/array)
while StringDecoder in "*/*" mode will not fail.
Issue: SPR-15374
This commit introduces a `useRegisteredExtensionsOnly` property that
indicates whether classes that use the `MediaTypeFactory` for supplying
default media types can do so.
- In classes that were introduced in Spring 5.0, the
`useRegisteredExtensionsOnly` property takes the place of the
`useJaf` property that was removed in 0aaa652
- In classes that existed before Spring 5.0, the
`useRegisteredExtensionsOnly` property is added in addition to the
deprecated `useJaf`, the latter delegating to the former, but with
flipped behavior.
Issue: SPR-14908
This commit changes the `MediaTypeFactory` to return
`Optional<MediaType>` (instead of a plain `MediaType`) for the
`getMediaType` methods.
Issue: SPR-14908
CharSequenceEncoder now supports all MIME types, however since encoding
Flux<String> can overlap with other encoders (e.g. SSE) there are now
two ways to create a CharSequenceEncoder -- with support for text/plain
only or with support for any MIME type.
In WebFlux configuration we insert one CharSequenceEncoder for
text/plain (as we have so far) and a second instance with support for
any MIME type at the very end.
Issue: SPR-15374
This commit changes `ServerResponse` and subtypes to use properties
instead of fields during response rendering. This allows for overriding
these methods in a response subclass.
This commit changes the `HandlerFilterFunction.ofResponseProcessor`
method signature to return `Mono<ServerResponse>`, to better cooperate
with response builders (which all return a `Mono`).
Instead of accepting List<Encoder|Decoder> and then look for the first
to support JSON, always expect a single JSON [Encoder|Decoder] and use
that unconditionally.
When writing use the nested ResolvableType instead of the Class of the
actual value which should better support generics.
Remove the SSE hint and pass "text/event-stream" as the media type
instead to serve as a hint. We are expecting a JSON encoder and using
it unconditionally in any case so this should be good enough.
Consolidate JsonView hint extraction in shared base class.
Rename base class from AbstractJackson2Codec to Jackson2CodecSupport
since the class mainly provides support methods.
ServerHttpMessage[Reader|Writer] are now expected for WebFlux,
annotated controller endpoint and subsequently the instanceof checks
for HttpMessage[Reader|Writer] vs ServerHttpMessage[Reader|Writer] can
be removed from AbstractMessageReaderArgumentResolver and
AbtractMessageWriterResultHandler.
Support for flushing in EncoderHttpMessageWriter is now driven from a
configurable list of "streaming" media types with the list including
"application/stream+json" by default.
As a result Jackson2ServerHttpMessageWriter is no longer needed.
ServerHttpEncoder and ServerHttpDecoder are HTTP-specific
specializations that can prepare encoding and decoding hints from
extra information available on the server side.
As a result Jackson2ServerHttpMessageReader is no longer needed.
There is a natural way to implement ServerHttpMessage[Reader|Writer]
from [Encoder|Decoder]HttpMessageWriter by resolving hints first via
a protected method and then delegating to the regular read or write.
There is no downside either since it does not prevent
[Encoder|Decoder]HttpMessageWriter from being used for both client and
server scenarios while they're more useful.
As a positive side effect AbstractServerHttpMessage[Reader|Writer] can
be removed further simplfications can be made (in a future commit) to
accept ServerHttpMessageWriter for configuration purposes on the server
side and remove instanceof checks for ServerHttpMessageWriter.
This commit updates the main code base to conform to the dropped JAF
dependency in MediaTypeFactory. Specifically, it
- Removes JAF detection (JAF_PRESENT constants)
- Deprecated useJaf properties, with no direct replacement.
- Updated docs to remove JAF references, in favor of MediaTypeFactory.
Issue: SPR-14908
Fold ResourceRegionHttpMessageWriter into ResourceHttpMessageWriter.
The latter was a private helper (not meant to be exposed) and the two
have much in common now sharing a number of private helper methods.
The combined class does not extend AbstractServerHttpMessageConverter
from which it was not using anything.
Internally the combined class now delegates directly to ResourceEncoder
or ResourceRegionEncoder as needed. The former is no longer wrapped
with EncoderHttpMessageWriter which is not required since "resource"
MediaType determination is a bit different.
The consolidation makes it easy to see the entire algorithm in one
place especially for server side rendering (and HTTP ranges). It
also allows for consistent determination of the "resource" MediaType
via MediaTypeFactory for all use cases.
ResourceRegionHttpMessageWriter no longer extends from
EncoderHttpMessageWriter freeing it to pass the correct content type
into the encoder.
Considering that the main benefit of EncoderHttpMessageWriter is to
deal with content type fallback cases, there is nothing to be missed.
Furthermore ResourceRegionHttpMessageWriter is a package private class
that is used internally within ResourceHttpMessageWriter and never
exposed externally as a an actual HttpMessageWriter.
Issue: SPR-15358
CompositeHttpHandler is public and called ContextPathCompositeHandler.
Also an overhaul of the Javadoc on HttpHandler, WebHttpHandlerAdapter,
and ContextPathCompositeHandler.
Switch from extension to delegation model, i.e. delegating to
InvocableHandlerMethod, so that only sync invocation is exposed and
only resolvers of type SyncHandlerMethodArgumentResolver are allowed
to be configured in a cleaner fashion.
Currently the BOM versions are:
* reactor-core 3.0.6.BUILD-SNAPSHOT
* reactor-netty 0.6.2.BUILD-SNAPSHOT
This commit fixes as well a few deprecations in reactor-core.
From spring-webflux to spring-web test sources since it is perfectly
usable for testing Spring MVC annotation method support.
Potentially to be promoted further up for use in any module that has
annotation method support. It has spring-core dependencies only
In preparation for SPR-15132.
Turn the BindingContextFactory into ModelInitializer (both package
private) since creating BindingContext itself is quite simple.
The ModelInitializer also has only one field and no need to be aware
of fields the RequestMappingHandlerAdapter.
- typealias to replace types like RouterDsl.() -> Unit by Routes
- String.invoke() as path("/foo") shortcut
- String.route() as pathPrefix("/foo").route() shortcut
- Avoid requiring PathPredicates.* import
Issue: SPR-15292
This commit adds a trailing slash to the nested path if the request path
also ends with a slash. For instance, given the request "/foo/bar/", and
nested path pattern "/foo/**", we expect the nested path to be “/bar/”,
not “/bar".
Removed `json()`, `html()` and `xml()` from `RequestPredicates`, since
they were confusingly named and would also require a counterpart that
reads the request `Content-Type` instead of the `Accept` header.
Renamed `RouterFunction.andSame()` to `and()`, and `and()` to
`andOther()`. The reason for this change is that we can expect most
RouterFunctions to be parameterized over ServerResponse, and thus it
makes sense to use the shortest composition method (`and()`) for
composing router functions of the same type.
When a user composes different response types, such as composing a
`RouterFunction<RenderingResponse>` with an
`RouterFunction<EntityResponse<?>`, the `andOther` method is to be used,
but this is a less common scenario.
Added RequestPredicate for JSON, HTML, and XML requests. All three tests
for their respective mime type in the Accept header, as well as checking
for a file extension.
This commit removes the parameterisation from ClientRequest, similarly
to ServerResponse. Dropping the parameterisation facilitates a
ClientRequest.from method that also copies the body of the target
request.
SPR-15234 Work in Progress
This commit reduces the exposition of `PathPattern` instances throughout
the `HandlerMapping` API and removes some methods from its public API.
Issue: SPR-14544
This commit reverses 9efa976d31, and adds
code comments to highlight why some Body[Inserter|Extractor] instances
returned from Body[Inserters|Extractors] use
ServerHttp[Request|Response] instead of using
Reactive[Input|Output]Message.
Since the introduction of `PathPatternRegistry`, the various path match
configuration flags are no longer needed in several places and that
configuration can live in the registry itself.
Issue: SPR-14544
This commit adds the new `PathPatternRegistry`, which holds a
sorted set of `PathPattern`s and allows for searching/adding patterns
This registry is being used in `HandlerMapping` implementations and
separates path pattern parsing/matching logic from the rest. Directly
using `PathPattern` instances should improve the performance of those
`HandlerMapping` implementations, since the parsing and generation of
pattern variants (trailing slash, suffix patterns, etc) is done only
once.
Issue: SPR-14544
This commit introduces a PathPatternParser which parses request pattern
strings into PathPattern objects which can then be used to fast
match incoming string paths. The parser and matching supports the syntax
as described in SPR-14544. The code is optimized around the common usages
of request patterns and is designed to create very little transient
garbage when matching.
Issue: SPR-14544
Prior to this commit, WebFlux would look at the handler method
annotations (`@ResponseStatus`) for each handler execution, even calling
the expensive `synthesizeAnnotation`.
This commit moves this logic to the InvocableHandlerMethod so that this
executed once at instantiation time and for all result handlers.
Issue: SPR-15227
Before this change the write Publisher was saved and Mono.empty()
returned from the write metohd which did not properly implement
the write contract since no writing ("consuming") was done.
This can be a problem in some cases. For example the request may appear
to succeed even if the publisher produces an error later when
subscribed to later after request handling completes.
This commit introduces a writeHandler function in the mock request and
response. By default it "writes" by consuming the content immediately,
which allows it to return a Mono<Void> that properly reflects when
writing is done, and it also caches the data so it may be replayed
later for test assertions.
For streaming scenario a custom writeHandler may be registered which
allows the custom handling to determine how long to stream before
cancelling so request handling may complete.
Issue: SPR-14590
This commit introduces JSON streaming support which
consists of serializing HTTP request with
application/stream+json media type as line delimited JSON.
It also optimize Flux serialization for application/json by
using flux.collectList() and a single Jackson invocation
instead of one call per element previous strategy.
This change result in a x4 throughput improvement
for collection with a lot of small elements.
Issues: SPR-15095, SPR-15104
The base URI is ignored for requests that include a host.
WebClient exposes UriBuilder (rather than UriBuilderFactory) for
per-request URI building based on the base URI. That provides
full control to add or replace components of the base URI.
Leave only one static, no-arg build() method for access to a Builder.
URI-related preferences are now exposed on the builder itself.
Improve Javadoc with base URI examples.