问题描述
SpringBoot 项目,当返回前端的数据类型为 Map 的时候,在 Map 中 put() 时间对象会出现以下问题:
- 传递的 Date 对象会变成时间戳
- 传递的 LocalDateTime 对象会变成数组
问题复现
编写一个 Controller 方法,返回值为 Map,分别 put() Date 对象和 LocalDateTime 对象。
@RestController @RequestMapping("test") public class TestController { @ApiOperation("t1") @GetMapping("t1") public Map
t1() { return new HashMap (){{ put("java.util.Date", new Date()); put("java.time.LocalDate", LocalDate.now()); put("java.time.LocalTime", LocalTime.now()); put("java.time.LocalDateTime", LocalDateTime.now()); }}; } } 访问接口,获得的数据如下,可以看到 Date 对象被转换成时间戳,而 LocalDateTime 对象被转换成数组。
解决问题
在上面复现问题时,我们发现 Date、LocalDate、LocalTime、LocalDateTime 对象数据在返回给前端的时候,并不是我们预期想要的值,在 SpringBoot 中,支持我们自定义对象类型的消息转换器,可以分别为各种对象的数据进行格式化,下面案例对 Date、LocalDate、LocalTime、LocalDateTime 四个对象进行消息转换。
创建自定义消息处理器可以通过重写 WebMvcConfigurer.extendMessageConverters() 方法来实现,代码如下:
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.module.SimpleModule; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.io.IOException; import java.text.SimpleDateFormat; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.List; /** * @author jiale */ @Configuration // 配置注解记得加上 public class WebMvcConfig implements WebMvcConfigurer { /** * 扩展的消息转换器 */ @Override public void extendMessageConverters(List
> converters) { /* * 解决 LocalDateTime 返回给前端会变成数组的问题 */ MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); ObjectMapper mapper = converter.getObjectMapper(); // 不显示为 null 的字段 mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); SimpleModule module = new SimpleModule(); // Date 消息转换器 module.addSerializer(Date.class, new JsonSerializer () { @Override public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { // 对时间进行格式化,返回数据为字符串类型 jsonGenerator.writeString(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date)); } }); // LocalDate 消息转换器 module.addSerializer(LocalDate.class, new JsonSerializer () { @Override public void serialize(LocalDate localDate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeString(DateTimeFormatter.ofPattern("yyyy-MM-dd").format(localDate)); } }); // LocalTime 消息转换器 module.addSerializer(LocalTime.class, new JsonSerializer () { @Override public void serialize(LocalTime localTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeString(DateTimeFormatter.ofPattern("HH:mm:ss").format(localTime)); } }); // LocalDateTime 消息转换器 module.addSerializer(LocalDateTime.class, new JsonSerializer () { @Override public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { jsonGenerator.writeString(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(localDateTime)); } }); // 如果还需要其它对象的消息转换器,就继续通过 module.addSerializer() 添加 mapper.registerModule(module); converter.setObjectMapper(mapper); // SpringBoot 默认提供了好多个消息转换器,这里把我们自定义的消息转换器放首个位置 converters.add(0, converter); } } 添加时间对象的消息处理器之后,返回前端的数据如下:
问题搞定!
还没有评论,来说两句吧...