【问题标题】:Jackson Timestamp wrong deserialization杰克逊时间戳错误的反序列化
【发布时间】:2019-07-05 20:54:18
【问题描述】:

我有一个自定义对象映射器类:

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import org.codehaus.jackson.map.ObjectMapper;


public class CustomObjectMapper extends ObjectMapper {
public static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssZ";

public CustomObjectMapper() {
    DateFormat df = new SimpleDateFormat(DATE_FORMAT);
    this.setDateFormat(df);
}

还有一个单元测试:

@Test
public void testSerialization() throws JsonParseException, JsonMappingException, IOException  {

    String timestamp = "2019-02-12T07:53:11+0000";
    CustomObjectMapper customObjectMapper = new CustomObjectMapper();
    Timestamp result = customObjectMapper.readValue(timestamp, Timestamp.class);
    System.out.println(result.getTime());

}

junit-test 给了我“2019”。

我尝试使用 customTimestampDeserializer:

public class CustomJsonTimestampDeserializer extends
    JsonDeserializer<Timestamp> {

@Override
public Timestamp deserialize(JsonParser jsonparser,
        DeserializationContext deserializationcontext) throws IOException,
        JsonProcessingException {

    String date = jsonparser.getText(); //date is "2019"
    JsonToken token = jsonparser.getCurrentToken(); // is JsonToken.VALUE_NUMBER_INT
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
            CustomObjectMapper.DATE_FORMAT);
    try {
        return new Timestamp(simpleDateFormat.parse(date).getTime());
    } catch (ParseException e) {

        return null;
    }
}

}

我做错了什么?似乎杰克逊认为时间戳字符串是一个整数,并且在 2019 年之后停止解析它。

【问题讨论】:

  • 你使用来自java.sqlTimestamp吗?
  • 我建议你不要使用SimpleDateFormatTimestamp。这些类设计不良且过时,尤其是前者,尤其是出了名的麻烦。而是使用来自java.time, the modern Java date and time APIInstant

标签: java json jackson timestamp deserialization


【解决方案1】:

这种方法有两个问题。

首先,有一个可疑的import语句:

import org.codehaus.jackson.map.ObjectMapper;

org.codehaus 是当前com.fasterxml 的前身。不清楚是不是故意用的,不过ObjectMapper的import应该是

import com.fasterxml.jackson.databind.ObjectMapper;

其次,不能像这样直接从纯字符串中读取时间戳

String timestamp = "2019-02-12T07:53:11+0000";

ObjectMapper 需要一个 JSON 字符串。所以如果是

{ "timestamp": "2019-02-12T07:53:11+0000" }

和一个包装类

class TimestampWrapper {

  private Timestamp timestamp;
  // getter + setter for timestamp
}

那么测试序列将正确执行:

String timestamp = "{ \"timestamp\": \"2019-02-12T07:53:11+0000\" }";
CustomObjectMapper customObjectMapper = new CustomObjectMapper();
TimestampWrapper result = customObjectMapper.readValue(timestamp, TimestampWrapper.class);
System.out.println(result.getTimestamp());

更新:

或者,不使用专门的包装类,可以从 JSON 数组反序列化:

String timestamp = "[ \"2019-02-12T07:53:11+0000\" ]";
CustomObjectMapper customObjectMapper = new CustomObjectMapper();
Timestamp[] result = customObjectMapper.readValue(timestamp, Timestamp[].class);
System.out.println(result[0]);

【讨论】:

  • { "timestamp": "2019-02-12T07:53:11+0000" }
【解决方案2】:

可能是 Jackson 没有将 Timestamp 识别为日期类型,因此不依赖 DateFormat

您可以尝试使用Java.util.Date 代替Timestamp 吗?

【讨论】:

    猜你喜欢
    • 2019-08-26
    • 2017-04-25
    • 2017-12-26
    • 1970-01-01
    • 2015-04-07
    • 1970-01-01
    • 2014-01-05
    相关资源
    最近更新 更多