This commit adds support for Model-related return values types such as
Map, Model, @ModelAttribute annotated, and non-simple types, which
helps to clarify the logic in ViewResolutionResultHandler.
In order to be more "reactive", changed StringDecoder's default from
merging all buffers in the stream to a single buffer into splitting the
buffers along newline (\r, \n) characters.
This commit introduces DataBuffer.indexOf(IntPredicate) and
lastIndexOf(IntPredicate), for finding the index of a byte in a
DataBuffer.
It also introduces DataBufferUtils.tokenize, which tokenizes a
DataBuffer into separate tokens, given a delimiter function.
While View and ViewResolver play the same role as in spring-webmvc they
are now abstracted behind the HandlerResultHandler abstraction so that
top-level contracts don't reference them and the DispatcherHandler is
also unaware of their existence.
Furthermore view resolution and response body handling which are now at
the same level of abstraction (each is a HandlerResultHandler) will
also share code for content negotiation, so it makes sense for them to
be side by side.
This commit moves the reactive.view package to reactive.result.view
with the View and ViewResolver contracts (previously in the top-level
reactive package) also moving there.
When a null is returned from an @ResponseBody method, rather than
returning Mono.empty() immediately, convert it to Mono.empty() and
apply the same processing.
Currently that doesn't make a practical difference but it's more
accurate to do it this way. Eventually it may mean the possibility
to turn empty values into something through an extension point
as we do with ResponseBodyAdvice in Spring MVC today.
This commit introduces a pooled data buffer as a subtype of DataBuffer,
as well as various utility methods related to reference counting.
Additionally, Crelease calls have been introduced throughout the
codebase to properly dispose of pooled databuffers.
Rename two classes each adapting to WebHandler to avoid confusing them:
1. HttpWebHandlerAdapter adapts from the low level HttpHandler to any
WebHandler (e.g. DispatcherHandler).
2. SimpleHandlerAdapter adapts the plain WebHandler for use within the
DispatcherHandler.
This commit also fixes an issue in WebHttpHandlerBuilder to ensure that
WebExceptionHandler's are inserted before and not after WebFilter's.
The renaming makes it clear this exception is for use where 400 error
applies within a Spring web application where the error may be
associated with a MethodParameter, a BindingResult, and so on.
There is no need for BadRequestStatusException which can be expressed
with ResponseStatusException(HttpStatus.BAD_REQUEST, "reason").
This commit wraps up the previous commits:
- It uses HttpMessageConverter in the web.reactive.server package instead of Encoder/Decoder.
- It introduces tests for the Resource @ResponseBodies.
This commit introduces a reactive version of the HttpMessageConverter.
During the implementation of zero-copy support, it became apparent that
it was ueful to have a common abstraction between client and server that
operated on HttpMessages rather than DataBuffers.
Two HttpMessageConverter implementations are provided:
- The CodecHttpMessageConverter, based on Encoder/Decoder.
- The ResourceHttpMessageConverter, using zero-copy if available.
This commit introduces support for zero-copy file transfers in the HTTP
response, through the ZeroCopyHttpOutputMessage subinterface of
ReactiveHttpOutputMessage.
This commit introduces two DataBuffer improvements:
- The capability to read a Flux<DataBuffer> from an input stream or
channel.
- The capability to limit a Publisher<DataBuffer> to publish up until a
given maximum byte count.
Now that we have a CompositeContentTypeResolverBuilder with built-in
defaults, we switch to those defaults in places where a
ContentTypeResolver is used.
Rename to MappingContentTypeResolver and replace "fileExtension" with
"key" in methods to be more general (e.g. file extension or query
param). Also switch from List to Set for the return values.
A pretty complete equivalent to the same in spring-webmvc except for
CORS checks, and custom HTTP methods. Another notable difference is
that the "params" condition works on query params strictly.
This commit adds AbstractHandlerMethodMapping, a starting point for
AbstractHandlerMapping, and HttpRequestPathHelper with a similar
purpose to UrlPathHelper but based with ServerWebExchange as input.
- correct name of HttpHandlerHandlerAdapter to WebHandlerHandlerAdapter
- shorten SimpleHandlerResultHandler to SimpleResultHandler
- add HandlerResult constructor without Model
- update tests
This commit adds the "*/*" media type in the list of compatible media
types for the StringDecoder. This allows this decoder to decoder
payloads of any media type as long as the target type is String.
Fixes#87
This commit underlines the fact that the request created by a
ClientHttpRequestFactory should be augmented with a message body using
the `ClientHttpRequest#setBody` method before it is executed.
See #82
This commit makes messageEncoders a required argument for building a
client request - those are needed to actually encode the body object as
a reactive stream to be written to the HTTP request body.
Removed raw types usage in DefaultHttpRequestBuilder.
DefaultHttpRequestBuilder now uses a UriTemplateHandler to expand URI
templates + variables into a concrete URI.
Fixes#80, fixes#85, fixes#86
This commit introduces the new `WebClientException` for wrapping
client-side exceptions.
This exception is now thrown when now message encoder can be found for
writing the request body as an HTTP request message.
Fixes#83
This commit adds generics support for WebResponseExtractors.
Types should be described using a ResolvableType, which can be
created with static methods like:
// for the type Event<Registration>
ResolvableType.forClassWithGenerics(Event.class, Registration.class)
Fixes#89
- Introcuces XmlEventDecoder which decodes from DataBuffer to
javax.xml.stream.events.XMLEvent. It uses the Aalto async XML API if
available, but falls back to a blocking default if not.
- Refacors Jaxb2Decoder to use said XmlEventDecoder, and split the
stream of events into separate substreams by using the JAXB annotation
value, one stream for each part of the tree that can be unmarshaled to
the given type.
- Various improvements in the JAXB code.
This commit resolves a few comments brought forward during a review
meeting, specifically:
- It renames AbstractResponseBodyPublisher to
AbstractRequestBodyPublisher.
- It separates out registration logic into a register method.
- It moves the RequestBodyPublisher and ResponseBodySubscriber for the
Servlet 3.1 support back into ServletHttpHandlerAdapter.
WebResponseExtractor uses Mono.when with the response status, headers,
and the decoded body. However when the response body stream is empty
then when completes empty too.
This change adds defaultIfEmpty handling for en empty response body.
There is now an HttpCookie (simple name-value pair) and separately a
ServerHttpCookie sub-class with additional attributes that a server
can send to clients.
HttpHeaders is no longer the place to access cookies. Instead there is
a read-only HttpCookie map on ServerHttpRequest and a mutable
ServerHttpCookie map on ServerHttpResponse.
Cookies are stored in a map that preserves their order.
Claneup of the Servlet 3.1 support:
- moved RequestBodyPublisher to ServletServerHttpRequest
- moved ResponseBodySubscribera to ServletServerHttpResponse
- response body is now copied to ServletOutputStream in chunks, rather
than one big byte[]
This commit adds a View and ViewResolver contracts to support HTML
template based rendering.
ViewResolverResultHandler applies view resolution by iterating the
resolvers to resolve to a view and then use it to render.
A model is created and passed to argument resolvers including a new
ModelArgumentResolver. The model is then exposed for result handling
as a field in HandlerResult.
Rename result to returnValue and resultType to returnValueType to
reflect what they represent.
The returnValue getter is also wrapped as Optional since the value
returned from a handler may be null (e.g. void method, null value).
This commit adds `RxJava1WebResponseExtractors`, a static factory of
`WebResponseExtractor`s that are based on the RxJava1 composition API.
All extracted types are based on the `Single` and `Observable` types.
This commit adds the `WebClient`, which relies on several parts of our
infrastructure:
* a `ClientHttpRequestFactory` to drive the underlying client library
* a `HttpRequestBuilder` builder API to create the client request
* a `WebResponseExtractor` to extract the "low-level"
`ClientHttpResponse` into a higher level representation such as a
decoded body
The `WebResponseExtractors` helper class contains many extractor
implementations all based on the `Flux`/`Mono` composition API.
This commit adds the `ClientHttpRequest` and `ClientHttpResponse`
implementations for the RxNetty HTTP client.
This client library is based on the `Single` and `Observable`
composition API, so this has to be converted to the `Flux`/`Mono`
variants.
This commit introduces the `ClientHttpRequest` and `ClientHttpResponse`
implementations for the Reactor-Net HTTP client. This client is already
based on the `Flux` and `Mono` contracts.
This commit also adds a `AbstractClientHttpRequest` to support the
`ClientHttpRequest` implementations; it mirrors the
`AbstractServerHttpResponse` contract with a `beforeCommit` to register
`Supplier`s that should be notified before the request is committed.
This commit adds a `DefaultHttpRequestBuilder` and its companion static
builders in `HttpRequestBuilders`. This allows to build client requests
with a friendly builder API, inspired by Spring's MockMvc API.
This commit adds the base contracts for the Web client.
The "Reactive" prefixes of the previously commited contracts has been
removed to match the server ones.
Both the `ClientHttpRequest` and the `ServerHttpResponse` extend
`ReactiveHttpOutputMessage`, which now has a `beforeCommit` method,
necessary in both client and server implementations.
`HttpRequestBuilder` will be used by the developers to create requests
with a nice builder API. `ClientHttpRequestFactory` will provide support
for many HTTP client libraries in this new client.
WebServerExchange -> ServerWebExchange
Follows the same convention as in the http package also better allowing
the possibility for a client equivalent in the future.
WebToHttpHandlerBuilder -> WebHttpHandlerBuilder
WebToHttpHandlerAdapter -> WebHttpHandlerAdapter
More consistent with Spring conventions.
Introduce adapter and handler sub-packages under web.server following a
review prompted by the addition of the session package and the package
cycle it brought in based on dependency on session.WebSessionManager.
This commit adds initial support for a maintaining a server-side
session with attributes across HTTP requests. The WebSession
abstraction can be accessed via WebServerExchange from a WebFilter or
the target WebHandler.
The session sub-package contains additional abstractions for creating
and managing sessions providing a basis for extensibility (e.g. Spring
Session). Those include WebSessionManager, SessionIdStrategy, and
SessionStore along with a cookie-based session id strategy and an
in-memory session store in use by default.
Note that the current API does not provide a way to invalidate or
re-create the session from server side code.
setComplete replaces writeHeaders as a more general lifecycle method
to perform any kind of handling at the end of request processing, for
example to ensure headers are written if not already.
beforeCommit provides an extension point for an action to be invoked
just before the response is committed, e.g. adding headers/cookies.
Added DataBuffer and DataBufferAllocator, and provided a default NIO
ByteBuffer-based implementation of those, as well as a Netty
ByteBuf-based version.
Before this change use of ExceptionHandlingWebHandler did ensure no
error signals are allowed to escape (hence relying on runtime
behavior).
This change ensures the same is done even when
ExceptionHandlingWebHandler is not configured for use, at the lowest
level which is the WebToHttpHandlerAdapter.
When decoding buffers as plain strings, the StringDecoder returns a
Publisher that may produce one or more `onNext` events.
This is perfectly valid, but leads to errors when trying to convert the
resulting Publisher into a `reactor.Mono` or `rx.Single`.
If the original Publisher emits 2 or more `onNext` signals,
converting to:
* `rx.Single` will throw an error saying that the underlying Observable
"emitted too many elements"
* `reactor.Mono` may contain only the first emitted element
This commit adds a `AbstractRawByteStreamDecoder` that takes a
`SubscriberBarrier` to apply splitting/aggregation operations on the
received elements.
The `StringDecoder` class now inherits from this abstract class and
uses one of the provided `SubscriberBarrier` implementations to
buffer all received elements in a single buffer.