Spring-Jackson-反序列化Date时遇到的问题

今天遇到个问题,String —–> java.util.Date 竟然出错!不过log中也给出了出错原因,做出相应改动即可。

起因

  前端传过来的json有时间相关的字段,传的值是 "2017-02-07 10:20:07" ,在后台接收到这个json后,进行String 转 java.util.Date 额时候报以下错:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of java.util.Date from String value '2017-02-07 10:20:07': not a valid representation (error: Failed to parse Date value '2017-02-07 10:20:07': Can not parse date "2017-02-07 10:20:07": not compatible with any of standard forms ("yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd"))
at [Source: java.io.PushbackInputStream@78565506; line: 2, column: 27] (through reference chain: com.hxbb.controller.request.TipOffSaveRequest["createTime"])
at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:55) ~[jackson-databind-2.4.6.jar:2.4.6]
at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:810) ~[jackson-databind-2.4.6.jar:2.4.6]
at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseDate(StdDeserializer.java:740) ~[jackson-databind-2.4.6.jar:2.4.6]
at com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateBasedDeserializer._parseDate(DateDeserializers.java:176) ~[jackson-databind-2.4.6.jar:2.4.6]
at com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateDeserializer.deserialize(DateDeserializers.java:262) ~[jackson-databind-2.4.6.jar:2.4.6]
at com.fasterxml.jackson.databind.deser.std.DateDeserializers$DateDeserializer.deserialize(DateDeserializers.java:246) ~[jackson-databind-2.4.6.jar:2.4.6]
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:538) ~[jackson-databind-2.4.6.jar:2.4.6]
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:99) ~[jackson-databind-2.4.6.jar:2.4.6]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:306) ~[jackson-databind-2.4.6.jar:2.4.6]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:124) ~[jackson-databind-2.4.6.jar:2.4.6]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3066) ~[jackson-databind-2.4.6.jar:2.4.6]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2221) ~[jackson-databind-2.4.6.jar:2.4.6]
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:205) ~[spring-web-4.1.7.RELEASE.jar:4.1.7.RELEASE]
... 53 common frames omitted

解决方案

  • 1、根据log的提示
      log中有说明原因,是说我的String格式不正常,它不能进行反序列化,它支持的格式有:

  yyyy-MM-dd'T'HH:mm:ss.SSSZ
  yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
  EEE, dd MMM yyyy HH:mm:ss zzz
  yyyy-MM-dd

   那么,我们按照它的需求,改一下String的格式,即:2017-02-07T10:20:07Z ,这个问题就迎刃而解。但是,而我们一般的都是:yyyy-MM-dd HH:mm:ss 这种格式的,我不想委屈求全,怎么办?看下面。

  • 2、重写JsonDeserializer. deserialize()方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class CustomJsonDateDeserializer extends JsonDeserializer<Date> {
@Override
public Date deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = jp.getText();
try {
return format.parse(date);
} catch (ParseException e1) {
format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
try{
return format.parse(date);
}catch (ParseException e2) {
format = new SimpleDateFormat("yyyy-MM-dd");
try{
return format.parse(date);
}catch (ParseException e3) {
throw new RuntimeException(e3);
}
}
}
}
}

   代码粗糙了点,但是想要的效果达到了。这里,我们支持的格式有:yyyy-MM-dd'T'HH:mm:ss.SSS'Z' yyyy-MM-dd yyyy-MM-dd HH:mm:ss

   最后 记得在字段上加上注解:

1
2
@JsonDeserialize(using = CustomJsonDateDeserializer.class)
private Date createTime; // 时间

热评文章