Spring 配置 jackson 转换 Date、LocalDateTime

 

业务需求:把传给前端对象中的LocalDateTime 都转为时间戳。(JDK已升至8,所以全面使用LocalDateTime)

 

一,通过局部注解

    在指定的日期格式属性字段上添加注解

    入参格式化 , 该注解由Spring提供。

    @DateTimeFormat(pattern= "yyyy-MM-dd HH:mm:ss")

    出参格式化 ,该注解由jackson(jackson-annotations)提供,timezone要带上,不然显示的是0时区的时间

     @JsonFormat( pattern= "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")

 

然鹅,本项目项目后期才处理这个需求,所以懒得一个个去添加。而且注解太多影响阅读(个人习惯)。

二,全局配置

    1.转换Date

        a.Date转为时间戳

            配置了Jackson,默认就会把Date转为时间戳。

        b.Date转为指定格式的时间子串

            在 XML中配置如下,指定对应的dateFormat 即可

    
        
            
                
            
        
    

    2.转换LocalDateTime

        这里记录下如何把LocalDateTime 转为 时间戳,不用每次都去搜。

    Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
    long millis = instant.toEpochMilli();

        在jackson里要把LocalDateTime 转换,需要加入一个包

        
       		com.fasterxml.jackson.datatype
        	jackson-datatype-jsr310
            2.9.8
        

        配置 objectMapper

    @Bean
    @Primary
    public ObjectMapper jacksonObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        // 通过该方法对mapper对象进行设置,所有序列化的对象都将按改规则进行系列化
        // Include.Include.ALWAYS 默认
        // Include.NON_DEFAULT 属性为默认值不序列化
        // Include.NON_EMPTY 属性为 空("") 或者为 NULL 都不序列化,则返回的json是没有这个字段的。这样对移动端会更省流量
        // Include.NON_NULL 属性为NULL 不序列化,就是为null的字段不参加序列化
        // objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

        // 字段保留,将null值转为""
        objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer() {
            @Override
            public void serialize(Object o, JsonGenerator jsonGenerator,
                                  SerializerProvider serializerProvider)
                    throws IOException, JsonProcessingException {
                jsonGenerator.writeString("");
            }
        });

        JavaTimeModule javaTimeModule = new JavaTimeModule();
        /*javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));*/

        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
        // 自定义 全局把时间转为 时间戳
        javaTimeModule.addSerializer(Date.class, new DateToLongSerializer());
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateToLongSerializer());
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeToLongSerializer());


        objectMapper.registerModule(javaTimeModule);
        return objectMapper;
    } 
  

       其中LocalDateTimeToLongSerializer 代码如下,其他两个略

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;

public class LocalDateTimeToLongSerializer extends JsonSerializer {
    @Override
    public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator,
                          SerializerProvider serializerProvider) throws IOException {
        Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
        long millis = instant.toEpochMilli();
        jsonGenerator.writeNumber(millis);
    }
}

     然后配置 MappingJackson2HttpMessageConverter 

    
        
            
                application/json;charset=UTF-8
            
        
        
    

    按理应该就可以了,然鹅,项目里并无效果。苦苦找资料两小时。也是粗心,其中有个帖子可以解决问题,但是没有细看。主要没往这方面考虑(越是诡异的问题,越是简单的)。直到看到这篇  解决SpringMVC 返回Java8 时间JSON数据的格式化问题处理 。里面提到以下代码 优先级要比上面那个代码高。

    
        
        
            
                
                
                    
                        application/json;charset=UTF-8
                    
                
            
        
    

        到此问题解决!

        但是,即使后者优先级低,为什么无效呢?是不是还存在一个转化器截胡了?希望有大神相告

 

参考:

1. @DateTimeFormat 和 @JsonFormat 注解

2.解析Json之MappingJackson2HttpMessageConverter使用方法

3.spring boot添加 LocalDateTime 等 java8 时间类序列化和反序列化的支持

4.Java8 LocalDateTime转时间戳

5. SpringMVC使用@ResponseBody时返回json的日期格式、@DatetimeFormat使用注意  

灰常感谢以上作者。

你可能感兴趣的:(Spring 配置 jackson 转换 Date、LocalDateTime)