zoukankan      html  css  js  c++  java
  • jackson使用localdatetime转换json出现问题

    问题】                                  

    Demo:

    复制代码
      LocalDateTime dt = LocalDateTime.now();
            ObjectMapper mapper = new ObjectMapper();
            try {
                String json = mapper.writeValueAsString(dt);
                System.out.println(json);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
    复制代码

    Jackson默认序列化会将LocalDateTime序列化成:

    {"dayOfMonth":15,"dayOfWeek":"SUNDAY","dayOfYear":258,"hour":14,"minute":6,"month":"SEPTEMBER","monthValue":9,"nano":359000000,"second":55,"year":2019,"chronology":{"id":"ISO","calendarType":"iso8601"}}

    并且该字符串反序列化成LocalDateTime会报错:

    Cannot construct instance of `java.time.LocalDateTime`

    Demo:

    复制代码
        String json = "{"dayOfMonth":15,"dayOfWeek":"SUNDAY","dayOfYear":258,"hour":14,"minute":2,"month":"SEPTEMBER","monthValue":9,"nano":71000000,"second":46,"year":2019,"chronology":{"id":"ISO","calendarType":"iso8601"}}";
            ObjectMapper mapper = new ObjectMapper();
            try {
                LocalDateTime dt = mapper.readValue(json, LocalDateTime.class);
                System.out.println(dt);
            } catch (IOException e) {
                e.printStackTrace();
            }
    复制代码

     就算加了:

    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    mapper.registerModule(new JavaTimeModule());

    也会报如下错误:

    com.fasterxml.jackson.databind.exc.MismatchedInputException: Expected array or string.

    Demo:

    复制代码
     String json = "{"dayOfMonth":15,"dayOfWeek":"SUNDAY","dayOfYear":258,"hour":14,"minute":2,"month":"SEPTEMBER","monthValue":9,"nano":71000000,"second":46,"year":2019,"chronology":{"id":"ISO","calendarType":"iso8601"}}";
            ObjectMapper mapper = new ObjectMapper();
            try {
                mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
                mapper.registerModule(new JavaTimeModule());
                LocalDateTime dt = mapper.readValue(json, LocalDateTime.class);
                System.out.println(dt);
            } catch (IOException e) {
                e.printStackTrace();
            }
    复制代码

    【解决方案】                                                              

    思路:

      改变jackson内部序列化和反序列化LocalDateTime的方式,序列化时转换为时间戳,反序列化时将时间戳转换为LocalDateTime即可。

    代码:

    创建两个类,分别继承JsonSerializer和JsonDeserializer

    复制代码
    //时间序列化时变为时间戳
    public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
        @Override
        public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            jsonGenerator.writeNumber(localDateTime.toInstant(ZoneOffset.ofHours(8)).toEpochMilli());
        }
    }
    复制代码
    复制代码
    //时间戳反序列化时间
    public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
        @Override
        public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
            Long timestamp = jsonParser.getLongValue();
            return LocalDateTime.ofEpochSecond(timestamp / 1000, 0, ZoneOffset.ofHours(8));
        }
    }
    复制代码

    使用方法(序列化添加如下3行红色代码)

    复制代码
          LocalDateTime dt = LocalDateTime.now();
            ObjectMapper mapper = new ObjectMapper();
            try {
                JavaTimeModule timeModule = new JavaTimeModule();
                timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
                mapper.registerModule(timeModule);
                String json = mapper.writeValueAsString(dt);
                System.out.println(json);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
    复制代码

    * 经过此方式序列化得到的结果为:"1568528927273"

    使用方法(反序列化添加如下3行红色代码)

    复制代码
    String json = "1568528927273";
            ObjectMapper mapper = new ObjectMapper();
            try {
                JavaTimeModule timeModule = new JavaTimeModule();
                timeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
                mapper.registerModule(timeModule);
                LocalDateTime dt = mapper.readValue(json, LocalDateTime.class);
                System.out.println(dt);
            } catch (IOException e) {
                e.printStackTrace();
            }
    复制代码

     转自https://www.cnblogs.com/yzeng/p/11522411.html

  • 相关阅读:
    java中&和&&是怎么运算的
    struts中ActionForward 使用mapping.findForward如何传递get参数
    EL表达式_详解
    JSTL标签_详解
    inner join, left join, right join, full join 的区别
    CentOS7部署FastDFS+nginx模块
    一个实例明白AutoResetEvent和 ManulResetEvent的用法
    C#防止在画面上闪烁的Button
    C#中给Label控件设置BackgroundImage属性
    浅析C#异步操作
  • 原文地址:https://www.cnblogs.com/jasenin/p/12607738.html
Copyright © 2011-2022 走看看