Browse Source

Improve HTTP message reading/writing docs

Cross-reference sections on HttpMessageReader/Writer and
HttpMessageConverter and improve the content.

Issue: SPR-16260
pull/1639/head
Rossen Stoyanchev 7 years ago
parent
commit
7bf9b767fd
  1. 37
      src/docs/asciidoc/integration.adoc
  2. 56
      src/docs/asciidoc/web/webflux.adoc
  3. 24
      src/docs/asciidoc/web/webmvc.adoc

37
src/docs/asciidoc/integration.adoc

@ -1232,39 +1232,18 @@ to serialize only a subset of the object properties. For example: @@ -1232,39 +1232,18 @@ to serialize only a subset of the object properties. For example:
[[rest-message-conversion]]
==== HTTP message conversion
==== HTTP Message Converters
[.small]#<<web-reactive.adoc#webflux-codecs,Same in Spring WebFlux>>#
Objects passed to and returned from the methods `getForObject()`, `postForLocation()`,
and `put()` are converted to HTTP requests and from HTTP responses by
`HttpMessageConverters`. The `HttpMessageConverter` interface is shown below to give you
a better feel for its functionality
[source,java,indent=0]
[subs="verbatim,quotes"]
----
public interface HttpMessageConverter<T> {
// Indicate whether the given class and media type can be read by this converter.
boolean canRead(Class<?> clazz, MediaType mediaType);
// Indicate whether the given class and media type can be written by this converter.
boolean canWrite(Class<?> clazz, MediaType mediaType);
// Return the list of MediaType objects supported by this converter.
List<MediaType> getSupportedMediaTypes();
// Read an object of the given type from the given input message, and returns it.
T read(Class<T> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException;
// Write an given object to the given output message.
void write(T t, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException;
}
----
The `spring-web` module contains the `HttpMessageConverter` contract for reading and
writing the body of HTTP requests and responses via `InputStream` and `OutputStream`.
``HttpMessageConverter``'s are used on the client side, e.g. in the `RestTemplate`, and
also on the server side, e.g. in Spring MVC REST controllers.
Concrete implementations for the main media (mime) types are provided in the framework
and are registered by default with the `RestTemplate` on the client-side and with
`RequestMethodHandlerAdapter` on the server-side.
`RequestMethodHandlerAdapter` on the server-side (see
<<web.adoc#mvc-config-message-converters,Configuring Message Converters>>).
The implementations of ``HttpMessageConverter``s are described in the following sections.
For all converters a default media type is used but can be overridden by setting the

56
src/docs/asciidoc/web/webflux.adoc

@ -110,9 +110,10 @@ of RxJava or other reactive library. See <<webflux-reactive-libraries>> for more @@ -110,9 +110,10 @@ of RxJava or other reactive library. See <<webflux-reactive-libraries>> for more
[[webflux-programming-models]]
=== Programming models
The `spring-web` module contains the reactive foundation that underlies Spring WebFlux --
HTTP abstractions, Reactive Streams server adapters, reactive codecs, and a
core Web API whose role is comparable to the Servlet API but with non-blocking semantics.
The `spring-web` module contains the reactive foundation that underlies Spring WebFlux
including HTTP abstractions, Reactive Streams <<webflux-httphandler,adapters>> for supported
servers, <<webflux-codecs,codecs>>, and a core <<webflux-web-handler-api>> comparable to
the Servlet API but with non-blocking contracts.
On that foundation Spring WebFlux provides a choice of two programming models:
@ -425,31 +426,34 @@ to have the following detected: @@ -425,31 +426,34 @@ to have the following detected:
[[webflux-codecs]]
=== Codecs
=== HTTP Message Codecs
[.small]#<<integration.adoc#rest-message-conversion,Same in Spring MVC>>#
The `spring-web` module provides
The `spring-web` module defines the
{api-spring-framework}/http/codec/HttpMessageReader.html[HttpMessageReader] and
{api-spring-framework}/http/codec/HttpMessageWriter.html[HttpMessageWriter]
for encoding and decoding the HTTP request and response body with Reactive Streams.
It builds on lower level contracts from `spring-core`:
* {api-spring-framework}/core/io/buffer/DataBuffer.html[DataBuffer] -- abstraction for
byte buffers -- e.g. Netty `ByteBuf`, `java.nio.ByteBuffer`, see
<<core#databuffers, Data Buffers and Codecs>>.
* {api-spring-framework}/core/codec/Encoder.html[Encoder] -- serialize a stream of Objects
to a stream of data buffers
* {api-spring-framework}/core/codec/Decoder.html[Decoder] -- deserialize a stream of data
buffers into a stream of Objects
Basic `Encoder` and `Decoder` implementations exist in `spring-core` but `spring-web` adds
more for JSON, XML, and other formats. You can wrap any `Encoder` and `Decoder` as a reader
or writer with `EncoderHttpMessageWriter` and `DecoderHttpMessageReader`. There are some
additional, web-only reader and writer implementations for server-sent events, form data,
and more.
Finally, `ClientCodecConfigurer` and `ServerCodecConfigurer` can be used to initialize
a list of readers and writers. They include support for classpath detection and a
of defaults along with the ability to override or replace those defaults.
{api-spring-framework}/http/codec/HttpMessageWriter.html[HttpMessageWriter] contracts
for encoding and decoding the body of HTTP requests and responses via Rective Streams
``Publisher``'s. These contacts are used on the client side, e.g. in the `WebClient`,
and on the server side, e.g. in annotated controllers and functional endpoints.
The `spring-core` module defines the
{api-spring-framework}/core/codec/Encoder.html[Encoder] and
{api-spring-framework}/core/codec/Decoder.html[Decoder] contracts that are independent of
HTTP and rely on the {api-spring-framework}/core/io/buffer/DataBuffer.html[DataBuffer]
contract that abstracts different byte buffer representations such as the Netty `ByteBuf`
and `java.nio.ByteBuffer` (see <<core#databuffers, Data Buffers and Codecs>>).
An `Encoder` can be wrapped with `EncoderHttpMessageWriter` to be used as an
`HttpMessageWriter` while a `Decoder` can be wrapped with `DecoderHttpMessageReader` to
be used as an `HttpMessageReader`.
The `spring-core` module contains basic `Encoder` and `Decoder` implementations for
`byte[]`, `ByteBuffer`, `DataBuffer`, `Resource`, and `String`. The `spring-web` module
adds ``Encoder``'s and ``Decoder``'s for Jackson JSON, Jackson Smile, and JAXB2.
The `spring-web` module also contains some web-specific readers and writers for
server-sent events, form data, and multipart requests.
To configure or customize the readers and writers to use applications will typically use
`ClientCodecConfigurer` or `ServerCodecConfigurer`.

24
src/docs/asciidoc/web/webmvc.adoc

@ -2274,7 +2274,8 @@ You could access the part named "meta-data" with a `@RequestParam("meta-data") S @@ -2274,7 +2274,8 @@ You could access the part named "meta-data" with a `@RequestParam("meta-data") S
metadata` controller method argument. However, you would probably prefer to accept a
strongly typed object initialized from the JSON formatted data in the body of the
request part, very similar to the way `@RequestBody` converts the body of a
non-multipart request to a target object with the help of an `HttpMessageConverter`.
non-multipart request to a target object with the help of an
<<integration.adoc#rest-message-conversion,HttpMessageConverter>>.
You can use the `@RequestPart` annotation instead of the `@RequestParam` annotation for
this purpose. It allows you to have the content of a specific multipart passed through
@ -2314,7 +2315,8 @@ be bound to the value of the HTTP request body. For example: @@ -2314,7 +2315,8 @@ be bound to the value of the HTTP request body. For example:
}
----
You convert the request body to the method argument by using an `HttpMessageConverter`.
You convert the request body to the method argument by using an
<<integration.adoc#rest-message-conversion,HttpMessageConverter>>.
`HttpMessageConverter` is responsible for converting from the HTTP request message to an
object and converting from an object to the HTTP response body. The
`RequestMappingHandlerAdapter` supports the `@RequestBody` annotation with the following
@ -2422,8 +2424,7 @@ The above example will result in the text `Hello World` being written to the HTT @@ -2422,8 +2424,7 @@ The above example will result in the text `Hello World` being written to the HTT
response stream.
As with `@RequestBody`, Spring converts the returned object to a response body by using
an `HttpMessageConverter`. For more information on these converters, see the previous
section and <<integration.adoc#rest-message-conversion,Message Converters>>.
an <<integration.adoc#rest-message-conversion,HttpMessageConverter>>.
[[mvc-ann-responseentity]]
@ -2443,7 +2444,8 @@ also allows setting response headers: @@ -2443,7 +2444,8 @@ also allows setting response headers:
}
----
As with `@ResponseBody`, Spring uses `HttpMessageConverter` to
As with `@ResponseBody`, Spring uses
<<integration.adoc#rest-message-conversion,HttpMessageConverter>> to
convert from and to the request and response streams. For more information on these
converters, see the previous section and <<integration.adoc#rest-message-conversion,
Message Converters>>.
@ -3353,7 +3355,7 @@ This is a technique related to "Long Polling" that is known as "HTTP Streaming". @@ -3353,7 +3355,7 @@ This is a technique related to "Long Polling" that is known as "HTTP Streaming".
Spring MVC makes this possible through the `ResponseBodyEmitter` return value
type which can be used to send multiple Objects, instead of one as is normally
the case with `@ResponseBody`, where each Object sent is written to the
response with an `HttpMessageConverter`.
response with an <<integration.adoc#rest-message-conversion,HttpMessageConverter>>.
Here is an example of that:
@ -3412,11 +3414,11 @@ http://blog.pivotal.io/pivotal/products/websocket-architecture-in-spring-4-0[the @@ -3412,11 +3414,11 @@ http://blog.pivotal.io/pivotal/products/websocket-architecture-in-spring-4-0[the
=== Streaming raw data
`ResponseBodyEmitter` allows sending events by writing Objects to the
response through an `HttpMessageConverter`. This is probably the most common
case, for example when writing JSON data. However sometimes it is useful to
bypass message conversion and write directly to the response `OutputStream`
for example for a file download. This can be done with the help of the
`StreamingResponseBody` return value type.
response through an <<integration.adoc#rest-message-conversion,HttpMessageConverter>>.
This is probably the most common case, for example when writing JSON data.
However sometimes it is useful to bypass message conversion and write directly to the
response `OutputStream` for example for a file download. This can be done with the help
of the `StreamingResponseBody` return value type.
Here is an example of that:

Loading…
Cancel
Save