java - Jackson 时间戳错误反序列化

标签 java json jackson timestamp deserialization

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

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;
    }
}

}

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

最佳答案

这种方法有两个问题。

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

import org.codehaus.jackson.map.ObjectMapper;

org.codehaus 是当前 com.fasterxml 的前身。目前尚不清楚它是否是故意使用的,但 ObjectMapper 的导入应该是

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]);

关于java - Jackson 时间戳错误反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54646206/

相关文章:

java - Jackson ObjectMapper() 构造函数抛出 NoSuchMethod

java - 如何使用 Jersey API 从 Restful Web 服务发送和接收 JSON 数据

javascript - 具有动态数据集的动态 Javascript 多线图表

java - Lombok、Spring mongodb 和 jackson 构造函数问题

java - 将java程序(以表单)输入的值添加到sql数据库:

Python JSON解码报错TypeError : can't use a string pattern on a bytes-like object

java - 如何在java Rest API中使用GET方法调用传递json数据

Java 内部接口(interface)作为返回类型

java - Collections.sort() throws 比较方法违反了它的一般约定!异常(exception)

Java 7 使用可变参数重载