文章目录
一、何为消息转换器
二、默认的消息转换器
三、SpringBoot配置自定义消息转换器
1. 注册fastjson消息转换器
2. 将消息转换器配置到集合中
四、注意事项
五、总结
一、何为消息转换器
要想理解消息转换器,首先得知道消息是什么,在使用SpringMVC框架时,由前端发请求给后端,请求体中的内容就被称为消息,另外反过来,由后端发给前端的响应数据也是消息,那消息转换器又是来干嘛的呢?其实就是实现消息与Java对象的相互转换,将请求体中的消息转为Java对象,反过来将Java对象转为响应体中的消息,所以其实SpringMVC中的@RequestBody和@ResponseBody注解就是干的这个事。
二、默认的消息转换器
在SpringBoot项目中由于导入了web-start依赖,在org.springframework.web.servlet.config.annotation包下面的WebMvcConfigurationSupport类,在这个下面有个addDefaultHttpMessageConverters方法就是设置默认的消息转换器集合。下面是源码:
protected final void addDefaultHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
messageConverters.add(new ByteArrayHttpMessageConverter());
messageConverters.add(new StringHttpMessageConverter());
messageConverters.add(new ResourceHttpMessageConverter());
messageConverters.add(new ResourceRegionHttpMessageConverter());
if (!shouldIgnoreXml) {
try {
messageConverters.add(new SourceHttpMessageConverter());
} catch (Throwable var3) {
}
}
messageConverters.add(new AllEncompassingFormHttpMessageConverter());
if (romePresent) {
messageConverters.add(new AtomFeedHttpMessageConverter());
messageConverters.add(new RssChannelHttpMessageConverter());
}
Jackson2ObjectMapperBuilder builder;
if (!shouldIgnoreXml) {
if (jackson2XmlPresent) {
builder = Jackson2ObjectMapperBuilder.xml();
if (this.applicationContext != null) {
builder.applicationContext(this.applicationContext);
}
messageConverters.add(new MappingJackson2XmlHttpMessageConverter(builder.build()));
} else if (jaxb2Present) {
messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
}
}
if (kotlinSerializationJsonPresent) {
messageConverters.add(new KotlinSerializationJsonHttpMessageConverter());
}
if (jackson2Present) {
builder = Jackson2ObjectMapperBuilder.json();
if (this.applicationContext != null) {
builder.applicationContext(this.applicationContext);
}
messageConverters.add(new MappingJackson2HttpMessageConverter(builder.build()));
} else if (gsonPresent) {
messageConverters.add(new GsonHttpMessageConverter());
} else if (jsonbPresent) {
messageConverters.add(new JsonbHttpMessageConverter());
}
if (jackson2SmilePresent) {
builder = Jackson2ObjectMapperBuilder.smile();
if (this.applicationContext != null) {
builder.applicationContext(this.applicationContext);
}
messageConverters.add(new MappingJackson2SmileHttpMessageConverter(builder.build()));
}
if (jackson2CborPresent) {
builder = Jackson2ObjectMapperBuilder.cbor();
if (this.applicationContext != null) {
builder.applicationContext(this.applicationContext);
}
messageConverters.add(new MappingJackson2CborHttpMessageConverter(builder.build()));
}
}
可以发现实际上是默认就添加了添加了以下4种消息转换器:
messageConverters.add(new ByteArrayHttpMessageConverter());
messageConverters.add(new StringHttpMessageConverter());
messageConverters.add(new ResourceHttpMessageConverter());
messageConverters.add(new ResourceRegionHttpMessageConverter());
下面还会根据需要添加:
MappingJackson2HttpMessageConverter、Jaxb2RootElementHttpMessageConverter之类的消息转换器
总之来说,根据实际需求添加合适的消息转换器。比如下面这部分代码:
if (jackson2Present) {
builder = Jackson2ObjectMapperBuilder.json();
if (this.applicationContext != null) {
builder.applicationContext(this.applicationContext);
}
messageConverters.add(new MappingJackson2HttpMessageConverter(builder.build()));
} else if (gsonPresent) {
messageConverters.add(new GsonHttpMessageConverter());
} else if (jsonbPresent) {
messageConverters.add(new JsonbHttpMessageConverter());
}
该代码段首先检查是否存在Jackson2库。如果存在,则使用Jackson2ObjectMapperBuilder创建一个JSON消息转换器,并将其添加到消息转换器列表中。如果应用程序上下文已经存在,则将其传递给Jackson2ObjectMapperBuilder以便进行进一步的配置。
如果Jackson2库不可用,则检查是否存在Gson库。如果存在,则使用GsonHttpMessageConverter创建一个Gson消息转换器,并将其添加到消息转换器列表中。
如果Gson库也不可用,则检查是否存在JSON-B库。如果存在,则使用JsonbHttpMessageConverter创建一个JSON-B消息转换器,并将其添加到消息转换器列表中。
总结几种常见的消息转换器:
注意这里的读写内容都是指的HTTP消息内容,比如说读写JSON格式数据,就是HTTP消息是JSON格式, 读就是JSON格式字符串转Java对象,写就是Java对象转JSON字符串。
三、SpringBoot配置自定义消息转换器
首先明白,因为是基于SpringBoot进行配置,所以配置都是基于配置类进行配置,配置消息转换器是在WebMvcConfigure接口实现类中重写configureMessageConverters、或者是重写extendMessageConverters方法,具体这两个方法有什么不同,我在下面会进行说明
下面是一个相对简单的配置,如果有其它需求的,需要配置其它序列化特性的,我下面进行简单说明
1. 注册fastjson消息转换器
@Bean
public HttpMessageConverter fastJsonHttpMessageConverters() {
//1.使用FastJson消息转换器对象
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
//2.创建FastJson配置类对象
FastJsonConfig fastJsonConfig = new FastJsonConfig();
//3.通过配置类对象设置属性
//"PrettyFormat"特性可以使得输出的JSON格式具有良好的可读性,即每个属性都单独占据一行,
// 而不是将整个JSON字符串打印在一行中。这样做可以让JSON数据更加易读,方便人工阅读和调试
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
//设置日期格式
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
//将Long类型数据转为字符串
SerializeConfig.globalInstance.put(Long.class, ToStringSerializer.instance);
//为FastJson添加序列化配置实例
fastJsonConfig.setSerializeConfig(SerializeConfig.globalInstance);
//将FastJson配置添加到fastJSON消息转换器中
fastConverter.setFastJsonConfig(fastJsonConfig);
HttpMessageConverter<?> converter = fastConverter;
return converter;
}
2. 将消息转换器配置到集合中
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//将fastJson消息转换器添加到消息转换器集合中
converters.add(fastJsonHttpMessageConverters());
}
针对其它需求,还可以设置其它特性
1. 除了"PrettyFormat"特性外,Fastjson库还提供了很多其他的序列化特性,例如:WriteMapNullValue(输出空置字段)、WriteNullStringAsEmpty(String类型的空值输出为"")、WriteNullBooleanAsFalse(Boolean类型的空值输出为false)等等。这些特性可以根据实际情况进行设置,以满足具体的业务需求。
2. 除了ToStringSerializer,fastjson库还提供了其他的序列化方式,例如:
- LongCodec:将Long类型的数据序列化为数字形式,默认的Long序列化方式。
- JSONAwareSerializer:将实现了JSONAware接口的Java对象序列化为字符串形式。
- MapSerializer:将Map类型的数据序列化为JSON对象。
- ListSerializer:将List类型的数据序列化为JSON数组。
- ArraySerializer:将数组类型的数据序列化为JSON数组。
四、注意事项
1. 在处理的过程中,一旦发现哪个消息转换器适合当前需求,就会使用这个消息转换器进行读写,就不会再去使用其它消息转换器了,这样做的目的是为了高效,减少无效的转换操作。
2. 如果想要自定义的消息转换器能够生效,就得放到同类型的第一个,理由如上。
3. 注意区分configureMessageConverters和extendMessageConverters方法的不同,前者会覆盖掉原有的消息转换器集合,而只保留当前的集合,因此如果使用了这个方法,就会覆盖掉默认的消息转换器集合,因此这里得注意配置了新的会不会引起功能的缺失,比如说默认的实际上是支持基本的@RequestBody,@ResponseBody功能的,配置了新的也要支持,不能让这两个注解失效。如果担心的化,可以使用extendMessageConverters方法配置消息转换器,这样就不会覆盖,确保了安全。
五、总结
1. 理解消息转换器的含义、作用
2. 学会使用基于SpringBoot方式对消息转换器进行配置
3. 了解基本的序列化特性,其实还是序列化与反序列那里的配置,和消息转换器本身没有关系,比如说ToStringSerializer、WriteNullStringAsEmpty(String类型的空值输出为"")等特性
4. 理解configureMessageConverters和extendMessageConverters方法的不同,选择合适的方法,另外理解执行消息转换器的流程,防止我们自定义的消息转换器失效。
总的来说明白消息转换器就是一种转换工具,其实还是序列化与反序列化的原理,基于这一原理的组件罢了,所以你配置相关序列化的特性,其实还是使用像Jackon、fastjson框架进行相关特性的配置。