Spring message annotation converter and controller

1. What is the message converter?

@RequestBody @ResponseBody and two annotations were completion request message to the object and the object in response to the message conversion.
This flexible underlying message conversion mechanism, is newly introduced Spring3.x HttpMessageConverter types, i.e., the message converter mechanism.
HttpMessageConverter the primary interface and its various subclasses (StringHttpMessageConverter etc.) responsible for this mechanism, that is, the message converter.

2, the message converter structure: HttpMessageConverter

Structure of the message converter of FIG follows

  • HttpInputMessage This interface is internal SpringMVC of a Http request packets abstract
  • HttpOutputMessage This interface is internal SpringMVC abstract Http response to a message
  • HttpMessageConverter this interface at the highest level abstract interface to the message converter
  • Which read () method as the reference receiver HttpInputMessage, is responsible for reading the request message
    • canRead () method is responsible for determining whether the request packet can be processed by the message converter
  • Its write () method as the reference receiver HttpOutputMessage, responsible for the data write response packet
    • canWrite () method is responsible for determining whether the response message can be processed by the message converter

Interface Description Figure:

Interface Description

Request processing procedure is shown:

Flow Description

3, Spring call logic

3.1 HandlerMethodArgumentResolver interfaces and interfaces HandlerMethodReturnValueHandler

This statement is only two interfaces, define methods. Specific implementation is the final treatment.

  • HandlerMethodArgumentResolver request message is bound to a processing method parameter strategy interfaces
  • HandlerMethodReturnValueHandler is the return value of the processing method of interface processing strategy.

3.2 RequestResponseBodyMethodProcessor 类

  • This class implements both interfaces and HandlerMethodArgumentResolver HandlerMethodReturnValueHandler interface. It acts as analytical method parameters and return values ​​handle both roles.

3.2.1 HandlerMethodArgumentResolver implemented interface (resolveArgument () method)

  • See the source code can be achieved only logical explanation here to watch.
    • Turn into: resolveArgument () method → ​​readWithMessageConverters () method → ​​super.readWithMessageConverters () method
    • Then you can see first call HttpMessageConverter of canRead () method, after verification by calling read () method.

3.2.2 HandlerMethodReturnValueHandler implemented interface (handleReturnValue () method)

  • See the source code can be achieved only logical explanation here to watch.
    • 依次进入:handleReturnValue()方法→writeWithMessageConverters()方法[参数不同]→writeWithMessageConverters()方法[参数不同]
    • 然后可以看到先调用HttpMessageConverter的canWrite()方法,校验通过后调用write()方法。

4、HttpMessageConverter子类及其在SpringMVC中的使用

以我们代码中的一个配置作为说明,并具体理解这个加载过程:

<mvc:annotation-driven>
    <mvc:message-converters>
        <ref bean="fastJsonHttpMessageConverter"/>
        <ref bean="sourceHttpMessageConverter"/>
    </mvc:message-converters>
</mvc:annotation-driven>
 
<bean id="sourceHttpMessageConverter"
      class="org.springframework.http.converter.xml.SourceHttpMessageConverter">
    <property name="supportedMediaTypes">
        <list>
            <value>application/xml;charset=UTF-8</value>
            <value>text/xml;charset=UTF-8</value>
        </list>
    </property>
</bean>
 
<bean id="fastJsonHttpMessageConverter"
      class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
    <property name="supportedMediaTypes">
        <list>
            <value>text/plain;charset=UTF-8</value>
            <value>application/json;charset=UTF-8</value>
        </list>
    </property>
</bean>

4.1 注解的解析(注解控制器)及加载HttpMessageConverter

主要参考文章: SpringMVC关于json、xml自动转换的原理研究-附带源码分析 - format丶 - 博客园

对于注解的解析:<mvc:annotation-driven/>。该解析由类org.springframework.web.servlet.config.AnnotationDrivenBeanDefinitionParserparse()方法处理。

  • 源码路径:AnnotationDrivenBeanDefinitionParser类→parse()方法→getMessageConverters()方法。
    • 源码中可知,如果没有配置<mvc:message-converters>属性,则加载默认的HttpMessageConverter。
      • 默认的有4个基础的,和5个需要条件再加载的。(这部分不做说明,不属于本文内容)
    • 如果配置了,则只加载配置的HttpMessageConverter

如同上述配置,则只会加载两个sourceHttpMessageConverterfastJsonHttpMessageConverter

4.2 HttpMessageConverter的supportedMediaTypes属性作用

我们配置了多个HttpMessageConverter,而每个HttpMessageConverter可以处理哪些类型的请求则由supportedMediaTypes属性定义(不止该属性,但也是一部分)
这部分的具体使用在:

  • 读部分参考【3.2.1】,找到canRead方法的调用地方之后,我们看canRead方法的实现。
    • 以FastJsonHttpMessageConverter为例,它的canRead方法实现实际调用的时父类(AbstractHttpMessageConverter)的canRead方法实现
      • 父类的实现如下,可以看到有对supportedMediaType的过滤

至此,我们可以确定,XML的配置中的supportedMediaTypes会音响该消息转换器可以处理的请求。以上述配置为例,sourceHttpMessageConverter负责处理XML数据格式的请求;fastJsonHttpMessageConverter处理json格式的请求。

canWrite方法也会用到supportedMediaTypes,可以自行梳理。至此,消息转换器的配置以及生效过程就比较清晰了。

5、参考:

  1. SpringMVC 源码剖析(五)- 消息转换器 HttpMessageConverter - 相见欢的个人空间 - OSCHINA
    注:本篇博客就是该文章的翻版,所以原文很重要。
  2. SpringMVC关于json、xml自动转换的原理研究-附带源码分析 - format丶 - 博客园
    注:对配置的生效过程说明很详细,可以参考。
  3. Spring MVC Interpretation - - Do not worry, Loser -
    OSCHINA. Note: For the Spring XML configuration parsing explanation is very clear. Key: Label are resolved by subclasses BeanDefinitionParser interface to complete. There is detailed analysis for AnnotationDrivenBeanDefinitionParser.
  4. springMVC message converter (Message Converter) - Jane books
    Note: great, source code is also good explanation for custom message converter description.
  5. SpringMVC HttpMessageConverter matching rules - - SegmentFault Si No
    Note: matching rules, can not read very profound sense, the follow-up look.

Guess you like

Origin www.cnblogs.com/buwuliao/p/11859103.html