Jackson ObjectMapper:日期序列化和反序列化的问题

时间:2016-08-17 16:18:38

标签: java date jackson deserialization

我想在Jackson Deserializer禁用lenient 选项严格反序列化Date字段。

  

基本上,我希望下面的代码抛出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 - 8 - 2016”}

这一天的差异从哪里开始?

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

1 个答案:

答案 0 :(得分:1)

该属性上的@JsonFormat注释会覆盖向SimpleDateFormat注册的ObjectMapper。摆脱@JsonFormat,杰克逊将仅使用提供的SimpleDateFormat来解析日期并因为

而失败
sdf.setLenient(false);

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