TABLE OF CONTENTS
文章主要讲解下Spring框架中的HTTP消息转换器message-converters的使用,Spring框架的HTTP消息转换器的主要作用是将HTTP请求和响应中的消息内容与Java对象之间进行相互转换(序列化与反序列化),这些消息转换器可以处理JSON、XML、文本、二进制等数据类型。
数据转换流程:
Spring默认的内置HTTP消息转换器
添加的默认HTTP消息转换器源码:
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#addDefaultHttpMessageConverters
Spring MVC中,使用message-converters
标签来配置不同的消息转换器。下面是使用中需要注意的地方:
如果多个消息转换器支持相同的媒体类型时,Spring会选择第一个匹配的消息转换器进行处理请求和响应,因此在message-converter标签中配置时需要注意顺序,当然也可以通过实现WebMvcConfigurer接口的配置类,重写configureMessageConverters方法,自定义转换器的顺序。
下面是一些默认的HTTP消息转换器(具体实现可以查看org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#addDefaultHttpMessageConverters
)
org.springframework.http.converter.StringHttpMessageConverter
:这是Spring框架内置的消息转换器之一,用于处理文本数据。它能够将HTTP请求中的文本数据(通常是字符串)转换为Java字符串,并反之将Java字符串转换为HTTP响应的文本数据。ByteArrayHttpMessageConverter
:用于处理字节数组。StringHttpMessageConverter
:用于处理文本(字符串)数据。FormHttpMessageConverter
:用于处理表单数据。Jaxb2RootElementHttpMessageConverter
:用于处理XML数据(需要JAXB 2支持)。MappingJackson2HttpMessageConverter
:用于处理JSON数据(需要Jackson 2支持),需要依赖Jackson。ResourceHttpMessageConverter
:负责读取资源文件和写出资源文件数据;MappingJacksonHttpMessageConverter
:负责读取和写入json格式的数据;(当返回值是对象或者List,就由这个处理)AtomFeedHttpMessageConverter
:负责读取和写入Atom格式的数据;RssChannelHttpMessageConverter
:负责读取和写入RSS格式的数据;
如何配置HTTP转换器
HTTP消息转换器在spring-mvc.xml文件中进行下面配置,如果不配置则默认使用内置的HTTP消息转换器。下面了字符串的转换器为StringHttpMessageConverter,Json转换器使用FastJsonHttpMessageConverter。因为使用到了Fastjson三方类库,需要在pom文件中引入依赖。
1、XML配置方式:
spring-mvc.xml
1 | <mvc:annotation-driven> |
pom.xml
1 |
2、注解配置类方式
Spring 5以上采用Java 8语法,接口方法提供了default实现,没有必要通过继承适配器类WebMvcConfigurerAdapter重写方法,直接实现WebMvcConfigurer接口重写方法即可。
1 |
|
源码实现
HttpMessageConverterorg.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor
解析请求参数的方法resolveArgument()和处理返回值的方法handleReturnValue()
在项目启动的时候通过WebMvcConfigurationSupport进行加载,当getMessageConverters()被调用的时候会通过configureMessageConverters()、addDefaultHttpMessageConverters()和extendMessageConverters()三个方法进行初始话消息转换器。生成的消息转换器放在List
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport
返回响应时,会通过下面的方法调用http message converter进行转换
org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite#handleReturnValue
C:/Users/Tsukasa/.m2/repository/org/springframework/spring-webmvc/5.3.24/spring-webmvc-5.3.24-sources.jar!/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java:275
假如报No converter for [class java.util.HashMap] with preset Content-Type 'null']
之类的错误,证明没有找到合适的Http Message Converter。
1 | 2023-10-25 01:13:29.928 [WARN ] [http-nio-8081-exec-2] [org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver] [208] Resolved [org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class java.util.HashMap] with preset Content-Type 'null'] |
扩展定制
整体思路分为三步:
1、继承AbstractHttpMessageConverter类,根据序列化和反序列化规则,重写构造、readInternal、writeInternal、supports等相关方法;
2、通过message-converter标签或者继承WebMvcConfigurerAdapter类,配置自定义的HTTP消息转换器;
3、编写Controller控制器,修改前端请求格式为自定义格式。
似乎在执行http message converter的读取和写入操作前后,通过RequestResponseBodyAdviceChain提供了一些切面操作,可以通过实现RequestBodyAdvice或者ResponseBodyAdvice的方法来在执行前后执行一些操作。
/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodArgumentResolver.java:184
参考资料
SpringMVC03-HttpMessageConverter(自定义消息转换器)
Spring Mvc:HttpMessageConverter 消息转换器
SpringMVC流程分析(七):HttpMessageConverter——SpringMVC中的消息转换
声明:本站所有文章均为原创或翻译,遵循署名 - 非商业性使用 - 禁止演绎 4.0 国际许可协议,如需转载请确保您对该协议有足够了解,并附上作者名 (Tsukasa) 及原文地址