【问题标题】:Jackson ObjectMapper : Issues with date serialization and deserializationJackson ObjectMapper:日期序列化和反序列化问题
【发布时间】:2016-12-24 09:50:42
【问题描述】:

我想在Jackson Deserializer禁用宽松 选项以严格反序列化日期字段。

基本上,我希望下面的代码抛出 Exception 而不是 将33-Aug-2016 解析为02-Sep-2016

1. Order.java

package com.test.date;

import java.text.SimpleDateFormat;
import java.util.Date;

import com.fasterxml.jackson.annotation.JsonFormat;

public class Order {

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MMM-yyyy")
    private Date orderDate;

    public Date getOrderDate() {
        return orderDate;
    }

    public void setOrderDate(Date orderDate) {
        this.orderDate = orderDate;
    }

    public String getFormattedDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
        return "[ " + sdf.format(getOrderDate()) + " ]";
    }

}

2。 TestJackson.java

package com.test.date;

import java.io.IOException;
import java.text.SimpleDateFormat;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class TestJackson {

    public static void main(String[] args) throws JsonParseException,
            JsonMappingException, IOException {

        SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
        sdf.setLenient(false);
        ObjectMapper mapper = new ObjectMapper();
        mapper.setDateFormat(sdf);
        Order order = mapper.readValue("{\"orderDate\" : \"33-Aug-2016\"}",
                Order.class);
        System.out.println(order.getFormattedDate());

    }

}

输出

[2016 年 9 月 2 日]

我可以实现我自己的 Deserializer 类来执行此操作,但我正在寻找一些基于注释或对象映射器设置的方法。

更新:

我决定使用自定义反序列化器实现并发现另一个问题,但现在使用 序列化。更新后的代码如下:

1. Order.java

package com.test.date;

import java.text.SimpleDateFormat;
import java.util.Date;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

public class Order {

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MMM-yyyy")
    @JsonDeserialize(using = DateDeserializer.class)
    private Date orderDate;

    public Date getOrderDate() {
        return orderDate;
    }

    public void setOrderDate(Date orderDate) {
        this.orderDate = orderDate;
    }

    @JsonIgnore
    public String getFormattedDate() {
        SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");
        return "[ " + sdf.format(getOrderDate()) + " ]";
    }

}

使用自定义反序列化器,日期验证可以完美运行。但是,同一对象的序列化存在问题。请看下面:

2。 TestJackson.java

package com.test.date;

import java.io.IOException;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class TestJackson {

    public static void main(String[] args) throws JsonParseException,
            JsonMappingException, IOException {

        ObjectMapper mapper = new ObjectMapper();
        Order order = mapper.readValue("{\"orderDate\" : \"22-Aug-2016\"}",
                Order.class);


        System.out.println(mapper.writeValueAsString(order));

    }

}

输出

{"orderDate":"21-Aug-2016"}

这一天的差异从何而来?

如果我们使用自定义Deserializer,是否必须提供Serializer 的自定义实现?

【问题讨论】:

    标签: java date jackson deserialization


    【解决方案1】:

    属性上的@JsonFormat 注释会覆盖使用ObjectMapper 注册的SimpleDateFormat。去掉@JsonFormat,Jackson 将只使用提供的SimpleDateFormat 来解析日期并因为

    而失败
    sdf.setLenient(false);
    

    据我所知,@JsonFormat 没有 Feature 可以设置来控制宽大处理。

    【讨论】:

    • 只要所有Date 字段都遵循相同的模式,它就可以工作。是否可以在没有@JsonFormat 的情况下对不同的日期字段使用不同的模式?
    • @jnanthak 你真不走运 afaik。查看您的日期的来源,看看您是否可以从源头上修复它们。
    • 我决定实现一个自定义Deserializer,但现在Serialization 出现了一个新问题。相差一天,请查看我更新的帖子。
    • 从 Jackson 2.9+ 开始,有一个功能可以控制宽大处理:@JsonFormat(lenient = OptBoolean.FALSE)
    猜你喜欢
    • 2019-04-03
    • 2020-08-24
    • 2011-10-13
    • 1970-01-01
    • 2014-11-05
    • 1970-01-01
    • 2018-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多