出现问题:
当我们的日期数据作为json传到前端并展示时,发现日期不太美观
如:
解决方法:使用消息转换器统一处理
步骤:
1、扩展mvc框架的消息转换器
在WebMvcConfigurationSupport中有extendMessageConverters(扩展消息转化器的方法),
重写这个方法并载入对象转换器即可
/**
* 扩展mvc框架的消息转换器
* @param converters
*/
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
log.info("开始扩展消息转换器...");
//创建一个消息转化器对象
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
//设置对象转换器,可以将Java对象转为json字符串
converter.setObjectMapper(new JacksonObjectMapper());
//将我们自己的转换器放入spring MVC框架的容器中
converters.add(0,converter);
}
注意!要放在第一位否则会失效
2、对象转换器
package com.reggie.json;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES;
/**
* 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
* 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
* 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
*/
public class JacksonObjectMapper extends ObjectMapper {
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
//public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm";
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss";
public JacksonObjectMapper() {
super();
//收到未知属性时不报异常
this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
//反序列化时,属性不存在的兼容处理
this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
SimpleModule simpleModule = new SimpleModule()
//反序列化
.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
//序列化
.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)))
.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)))
.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT)))
.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT)));
//注册功能模块 例如,可以添加自定义序列化器和反序列化器
this.registerModule(simpleModule);
}
}
关于消息转化器的拓展:
消息转换器原理解析
详细可看原创 https://blog.csdn.net/shadabing/article/details/84664402/
在使用Spring框架过程中,很多框架内部实现都涉及到消息转换器。
- Spring MVC框架中,将HTTP请求信息转换为一个对象(@RequestBody注解),将对象输出为HTTP响应信息(@ResponseBody注解),都通过消息转换器HttpMessageConverter来进行不同类型对象转换。
- 在操作Redis数据库时,一般选用RedisTemplate或StringRedisTemplate,如何将对象存储到redis中,就涉及到序列化方式的选择,不同序列化方式,结果不一样,虽然序列化器不是转换器,但作用大体是一样的。
- 在使用RabbitMQ消息队列中,生产者需要将对象转换成消息写进消息队列,消费者需要将消息转换成对象读取,都离不开消息转换器MessageConverter进行消息转换。
我们知道存储到数据到本地磁盘或者传输数据到网络另一端,都是以字节为最小单位进行的,所以在存储或传输对象时,最终是对象与具体字节数据相互转换,而类型转换器或序列化框架作用正是如此。
转化原理图:![](https://i-blog.csdnimg.cn/blog_migrate/3ef41b45a00166b237c74378307060f3.png)
消息转换器的关系与作用:
作用:
名称 | 作用 | 读支持MediaType | 写支持MediaType | 备注 |
FormHttpMessageConverter | 表单与MultiValueMap的相互转换 | application/x-www-form-urlencoded | application/x-www-form-urlencoded和multipart/form-data | 可用于处理下载 |
XmlAwareFormHttpMessageConverter | Spring3.2后已过期,使用下面AllEnc…代替 | 略 | 略 | |
AllEncompassingFormHttpMessageConverter | 对FormHttp…的扩展,提供了对xml和json的支持 | 同上 | 同上 | |
SourceHttpMessageConverter | 数据与javax.xml.transform.Source的相互转换 | application/xml和text/xml和application/*+xml | 同read | 和Sax/Dom等有关 |
ResourceHttpMessageConverter | 数据与org.springframework.core.io.Resource | */* | */* | |
ByteArrayHttpMessageConverter | 数据与字节数组的相互转换 | */* | application/octet-stream | |
ObjectToStringHttpMessageConverter | 内部持有一个StringHttpMessageConverter和ConversionService | 它俩的&& | 它俩的&& | |
RssChannelHttpMessageConverter | 处理RSS <channel> 元素 | application/rss+xml | application/rss+xml | 很少接触 |
MappingJackson2HttpMessageConverter | 使用Jackson的ObjectMapper转换Json数据 | application/json和application/*+json | application/json和application/*+json | 默认编码UTF-8 |
MappingJackson2XmlHttpMessageConverter | 使用Jackson的XmlMapper转换XML数据 | application/xml和text/xml | application/xml和text/xml | 需要额外导包Jackson-dataformat-XML才能生效。从Spring4.1后才有 |
GsonHttpMessageConverter | 使用Gson处理Json数据 | application/json | application/json | 默认编码UTF-8 |
ResourceRegionHttpMessageConverter | 数据和org.springframework.core.io.support.ResourceRegion的转换 | application/octet-stream | application/octet-stream | Spring4.3才提供此类 |
ProtobufHttpMessageConverter | 转换com.google.protobuf.Message数据 | application/x-protobuf和text/plain和application/json和application/xml | 同read | @since 4.1 |
StringHttpMessageConverter | 数据与String类型的相互转换 | */* | */* | 转成字符串的默认编码为ISO-8859-1 |
BufferedImageHttpMessageConverter | 数据与java.awt.image.BufferedImage的相互转换 | Java I/O API支持的所有类型 | Java I/O API支持的所有类型 | |
FastJsonHttpMessageConverter | 使用FastJson处理Json数据 | */* | */* | 需要导入Jar包和自己配置,Spring并不默认内置 |