[Spring] functions and replacements of HttpMessageConverter,
I believe that Spring developers have used @ RequestBody and @ ResponseBody annotations. They can directly parse the input into Json and parse the output into Json. However, HTTP requests and responses are text-based, this means that the browser communicates with the server by exchanging original text, and HttpMessageConverter is actually playing a role here.
HttpMessageConverter
The Http Request Response packet is actually a string. When the request packet arrives in a java program, it is encapsulated as a ServletInputStream stream. The Developer then reads the packet, and the response packet is output through the ServletOutputStream stream.
Only the original string packets can be read from the stream, and the output stream is also. There is a conversion problem between a string and a java object when the packet arrives at SpringMVC/SpringBoot and spring boot. In SpringMVC/SpringBoot, this process is solved through HttpMessageConverter. HttpMessageConverter Interface source code:
public interface HttpMessageConverter<T> { boolean canRead(Class<?> clazz, MediaType mediaType); boolean canWrite(Class<?> clazz, MediaType mediaType); List<MediaType> getSupportedMediaTypes(); T read(Class<? extends T> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException; void write(T t, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException;}
The following is an example,
@RequestMapping("/test")@ResponseBodypublic String test(@RequestBody String param) { return "param '" + param + "'";}
Before the request enters the test method, the corresponding HttpMessageConverter implementation class will be selected based on the @ RequestBody annotation to resolve the request parameters to the param variable, because the parameters here are String-type, therefore, the StringHttpMessageConverter class is used here. Its canRead () method returns true, and the read () method reads the request parameters from the request and binds them to test () in the param variable of the method.
Similarly, after the test method is executed, SpringMVC/SpringBoot will use the StringHttpMessageConverter write () method to write the result as a String value to the response message because the return value identifies @ ResponseBody. Of course, the canWrite () method returns true.
Simply describe the entire process:
During Spring's processing, a request message and a response message are abstracted as a request message HttpInputMessage and a response message HttpOutputMessage.
When processing a request, the appropriate message converter binds the request message to a parameter object in the method. Here, the same object may have different message formats, such as json and xml. The same is true for responding to requests.
In Spring, there are different HttpMessageConverter implementation classes for different message forms to process various message forms. For different message parsing implementations, there are different HttpMessageConverter implementation classes.
Replace @ ResponseBody with the default HttpMessageConverter
Here is a SpringBoot demo. In SpringMVC/SpringBoot, annotations such as @ RequestBody use jackson by default to parse json. See the following example:
@Controller@RequestMapping("/user")public class UserController { @RequestMapping("/testt") @ResponseBody public User testt() { User user = new User("name", 18); return user; }}
public class User { private String username; private Integer age; private Integer phone; private String email; public User(String username, Integer age) { super(); this.username = username; this.age = age; }}
When the browser accesses/user/testt, the returned result is as follows:
This is the result of jackson parsing. Now we will use fastjson to parse the object. Here we will replace the default HttpMessageConverter, is to use FastJsonHttpMessageConverter to process the conversion between Java objects and HttpInputMessage/HttpOutputMessage.
First, create a configuration class to add and configure FastJsonHttpMessageConverter. Spring4.x is recommended to add annotations to Java configuration, that is, SpringBoot is even more like no xml file.
Import com. alibaba. fastjson. serializer. serializerFeature; import com. alibaba. fastjson. support. config. fastJsonConfig; import com. alibaba. fastjson. support. spring. fastJsonHttpMessageConverter; import org. springframework. boot. autoconfigure. web. httpMessageConverters; import org. springframework. context. annotation. bean; import org. springframework. context. annotation. configuration; import org. springframework. http. Converter. httpMessageConverter; import java. nio. charset. charset; @ Configurationpublic class HttpMessageConverterConfig {// introduce Fastjson to parse json, without using the default jackson // it must be in pom. xml introduces the fastjson jar package, and the version must be later than 1.2.10 @ Bean public HttpMessageConverters fastJsonHttpMessageConverters () {// 1. defines the convert conversion message object javasfastconverter = new FastJsonHttpMessageConverter (); // 2. Add fastjson configuration information FastJsonConf Ig fastJsonConfig = new FastJsonConfig (); SerializerFeature [] serializerFeatures = new SerializerFeature [] {// The output key contains double quotation marks // SerializerFeature. quoteFieldNames, // whether to output a null field. If it is null, the field // SerializerFeature is displayed. writeMapNullValue, // if the value field is null, the output is 0 SerializerFeature. writeNullNumberAsZero, // if the List field is null, the output is [] rather than null SerializerFeature. writeNullListAsEmpty, // if the character type field is null, the output is "", rather than null Serialize RFeature. writeNullStringAsEmpty, // If the Boolean field is null, the output is false, rather than null SerializerFeature. writeNullBooleanAsFalse, // Date converter SerializerFeature. writeDateUseDateFormat, // cyclically reference SerializerFeature. disableCircularReferenceDetect,}; fastJsonConfig. setSerializerFeatures (serializerFeatures); fastJsonConfig. setCharset (Charset. forName ("UTF-8"); // 3. Add the configuration information fastConverter in convert. setFastJsonConfig (fastJson Config); // 4. Add convert to converters. HttpMessageConverter <?> Converter = fastConverter; return new HttpMessageConverters (converter );}}
Here, if the value of the string type is null, "" is returned. If the value type is null, 0 is returned. Restart the application and access the/user/testt interface again. The following is returned:
We can see that all null values are converted to "" or "0.