HttpMessageConverter 简介

HttpMessageConverter 是SpringMVC中供给的一个策略接口,它是一个音讯转化器类,Spring Mvc中便是由HttpMessageConverter担任转化HTTP的恳求和呼应。

默认情况下,Spring Boot 会自动加载如下音讯类型转化器:

Spring Mvc:HttpMessageConverter 消息转换器

常见音讯类型转化器介绍:

  • StringHttpMessageConverter:担任读取字符串格局的数据和写出二进制格局的数据(当返回值是或者接受值是String类型时,是由这个处理)
  • MappingJacksonHttpMessageConverter:担任读取和写入json格局的数据;(当返回值是目标或者List,就由这个处理)
  • ByteArrayHttpMessageConverter:担任读取二进制格局的数据和写出二进制格局的数据;
  • FormHttpMessageConverter:担任读取form提交的数据(能读取的数据格局为 application/x-www-form-urlencoded,不能读取multipart/form-data格局数据);担任写入application/x-www-from-urlencoded和multipart/form-data格局的数据;
  • ResourceHttpMessageConverter:担任读取资源文件和写出资源文件数据;
  • SourceHttpMessageConverter:担任读取和写入xml中javax.xml.transform.Source定义的数据;
  • Jaxb2RootElementHttpMessageConverter:担任读取和写入xml 标签格局的数据;
  • AtomFeedHttpMessageConverter:担任读取和写入Atom格局的数据;
  • RssChannelHttpMessageConverter:担任读取和写入RSS格局的数据;

数据转化流程

使用SpringMVC结构,能够使得我们在开发时,只要在代码中使用@RequestBody和@ResponseBody两个注解,就能够别离完成从恳求报文到目标和从目标到呼应报文的转化。而在源码内部,其实这种灵活的音讯转化机制便是使用HttpMessageConverter来完成的。

HttpMessageConverter的调用是RequestResponseBodyMethodProcessor类的解析恳求参数的办法resolveArgument()和处理返回值的办法handleReturnValue()中进行调用的。这是关于@RequestBody和@ResponseBody两个注解的原理。

Spring Mvc:HttpMessageConverter 消息转换器

音讯转化器接口

public interface HttpMessageConverter<T> {
	boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
	boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
	List<MediaType> getSupportedMediaTypes();
	default List<MediaType> getSupportedMediaTypes(Class<?> clazz) {
		return (canRead(clazz, null) || canWrite(clazz, null) ?
				getSupportedMediaTypes() : Collections.emptyList());
	}
	T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
			throws IOException, HttpMessageNotReadableException;
	void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
			throws IOException, HttpMessageNotWritableException;
}

转化器加载流程

音讯转化器是在项目发动的时分经过WebMvcConfigurationSupport进行加载,当getMessageConverters()被调用的时分会经过configureMessageConverters()、addDefaultHttpMessageConverters()和extendMessageConverters()三个办法进行初始话音讯转化器。生成的音讯转化器放在List<HttpMessageConverter<?>> messageConverters集合中

	protected final List<HttpMessageConverter<?>> getMessageConverters() {
        if (this.messageConverters == null) {
            this.messageConverters = new ArrayList();
            // 加载托付给WebMvcConfigurer类型的Bean
            this.configureMessageConverters(this.messageConverters);
            if (this.messageConverters.isEmpty()) {
                // 加载默认的转化器
                this.addDefaultHttpMessageConverters(this.messageConverters);
            }
            // 加载扩展音讯转化器
            this.extendMessageConverters(this.messageConverters);
        }
        return this.messageConverters;
    }

自定义音讯转化器

  1. FastJson 、Gson 等组件自带常用json音讯转化器
  2. 完成HttpMessageConverter 接口
  3. 承继 AbstractHttpMessageConverter 类

加载自定义音讯转化器

  1. 直接注入Bean 的办法替换
  2. 完成 WebMvcConfigurer#extendMessageConverters 接口办法
@Configuration
public class CustomWebMvcConfigurer implements WebMvcConfigurer {
    /**
     * 直接注入 HttpMessageConverters
     */
    @Bean
    public HttpMessageConverters customConverters() {
        return new HttpMessageConverters(configFastJsonHttpMessageConverter());
    }
    /**
     * 完成 WebMvcConfigurer#extendMessageConverters 接口
     */
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 注意加载次序
        converters.add(0, configFastJsonHttpMessageConverter());
    }
    /**
     * 装备JSON 音讯转化器
     */
    private HttpMessageConverter<Object> configFastJsonHttpMessageConverter() {
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        // 装备转化特性
        fastJsonConfig.setSerializerFeatures(
            SerializerFeature.DisableCircularReferenceDetect,
            SerializerFeature.WriteNonStringKeyAsString,
            SerializerFeature.WriteMapNullValue
        );
        converter.setFastJsonConfig(fastJsonConfig);
        // 设置处理音讯类型
        converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON));
        return converter;
    }
}