问题
I would like to disable lenient option in Jackson Deserializer to deserialize Date fields strictly.
Basically, I would like the below code to throw Exception instead of parsing
33-Aug-2016as02-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());
}
}
Output
[ 02-Sep-2016 ]
I can implement my own Deserializer class to do this, but I am looking for some annotation based or object mapper settings approach.
UPDATE:
I decided to go with custom Deserializer implementation and found another issue, but with Serialization now. The updated codes are for as shown below:
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()) + " ]";
}
}
With custom deserializer, validation of dates work perfectly. However, serialization of the same object has issues. Please see below:
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));
}
}
Output
{"orderDate":"21-Aug-2016"}
From where does this one day difference come into picture?
Is it mandatory to provide custom implementation of Serializer if we use a custom Deserializer?
回答1:
The @JsonFormat annotation on the property overrides the SimpleDateFormat registered with the ObjectMapper. Get rid of the @JsonFormat and Jackson will use only the supplied SimpleDateFormat to parse the date and fail because of the
sdf.setLenient(false);
As far as I know, @JsonFormat does not have a Feature you can set to control leniency.
来源:https://stackoverflow.com/questions/39001693/jackson-objectmapper-issues-with-date-serialization-and-deserialization