From 7bf9b767fda40f175123e96858cab0185c73ee7c Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 4 Jan 2018 21:15:04 -0500 Subject: [PATCH] Improve HTTP message reading/writing docs Cross-reference sections on HttpMessageReader/Writer and HttpMessageConverter and improve the content. Issue: SPR-16260 --- src/docs/asciidoc/integration.adoc | 37 +++++----------------- src/docs/asciidoc/web/webflux.adoc | 50 ++++++++++++++++-------------- src/docs/asciidoc/web/webmvc.adoc | 24 +++++++------- 3 files changed, 48 insertions(+), 63 deletions(-) diff --git a/src/docs/asciidoc/integration.adoc b/src/docs/asciidoc/integration.adoc index dbed4660b7..9bd4a325d0 100644 --- a/src/docs/asciidoc/integration.adoc +++ b/src/docs/asciidoc/integration.adoc @@ -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]#<># -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 { - - // 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 getSupportedMediaTypes(); - - // Read an object of the given type from the given input message, and returns it. - T read(Class 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 +<>). 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 diff --git a/src/docs/asciidoc/web/webflux.adoc b/src/docs/asciidoc/web/webflux.adoc index 0959744a5d..3543db2c3f 100644 --- a/src/docs/asciidoc/web/webflux.adoc +++ b/src/docs/asciidoc/web/webflux.adoc @@ -110,9 +110,10 @@ of RxJava or other reactive library. See <> 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 <> for supported +servers, <>, and a core <> 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: [[webflux-codecs]] -=== Codecs +=== HTTP Message Codecs +[.small]#<># -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}/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. -* {api-spring-framework}/core/io/buffer/DataBuffer.html[DataBuffer] -- abstraction for -byte buffers -- e.g. Netty `ByteBuf`, `java.nio.ByteBuffer`, see -<>. -* {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 +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 <>). +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`. -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. +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. -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. +To configure or customize the readers and writers to use applications will typically use +`ClientCodecConfigurer` or `ServerCodecConfigurer`. diff --git a/src/docs/asciidoc/web/webmvc.adoc b/src/docs/asciidoc/web/webmvc.adoc index 506905baf8..7c3d7ba745 100644 --- a/src/docs/asciidoc/web/webmvc.adoc +++ b/src/docs/asciidoc/web/webmvc.adoc @@ -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 +<>. 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: } ---- -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 +<>. `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 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 <>. +an <>. [[mvc-ann-responseentity]] @@ -2443,7 +2444,8 @@ also allows setting response headers: } ---- -As with `@ResponseBody`, Spring uses `HttpMessageConverter` to +As with `@ResponseBody`, Spring uses +<> to convert from and to the request and response streams. For more information on these converters, see the previous section and <>. @@ -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 <>. Here is an example of that: @@ -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 <>. +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: