解决 SpringBoot 的 Date、LocalDateTime 变成时间戳和数组的问题,创建自定义对象消息转换器

解决 SpringBoot 的 Date、LocalDateTime 变成时间戳和数组的问题,创建自定义对象消息转换器

码农世界 2024-05-18 前端 71 次浏览 0个评论

问题描述

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);
        }
    }
    

    添加时间对象的消息处理器之后,返回前端的数据如下:

    问题搞定!

转载请注明来自码农世界,本文标题:《解决 SpringBoot 的 Date、LocalDateTime 变成时间戳和数组的问题,创建自定义对象消息转换器》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,71人围观)参与讨论

还没有评论,来说两句吧...

Top