如何反映杰克逊在几秒钟内的时间戳?

问题描述 投票:26回答:4

我有一些JSON在几秒钟内有时间戳(即Unix时间戳):

{"foo":"bar","timestamp":1386280997}

要求杰克逊将其反序列化为具有时间戳的DateTime字段的对象,导致1970-01-17T01:11:25.983Z,这个时期之后不久,因为杰克逊假设它在几毫秒内。除了撕掉JSON并添加一些零之外,我怎样才能让杰克逊了解秒时间戳?

java json timestamp jackson unix-timestamp
4个回答
25
投票

我写了一个自定义deserializer来处理时间戳(几秒钟)(Groovy语法)。

class UnixTimestampDeserializer extends JsonDeserializer<DateTime> {
    Logger logger = LoggerFactory.getLogger(UnixTimestampDeserializer.class)

    @Override
    DateTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        String timestamp = jp.getText().trim()

        try {
            return new DateTime(Long.valueOf(timestamp + '000'))
        } catch (NumberFormatException e) {
            logger.warn('Unable to deserialize timestamp: ' + timestamp, e)
            return null
        }
    }
}

然后我注释了我的POGO用于时间戳:

class TimestampThing {
    @JsonDeserialize(using = UnixTimestampDeserializer.class)
    DateTime timestamp

    @JsonCreator
    public TimestampThing(@JsonProperty('timestamp') DateTime timestamp) {
        this.timestamp = timestamp
    }
}

14
投票
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="s")
public Date timestamp;

编辑:vivek-kothari建议

@JsonFormat(shape=JsonFormat.Shape.NUMBER, pattern="s")
public Timestamp timestamp;

8
投票

与@ DrewStephens的方法非常类似,它使用Java SE TimeUnit API(在JDK1.5中引入)而不是普通的字符串连接,因此(可以说)更清洁,更具表现力:

public class UnixTimestampDeserializer extends JsonDeserializer<Date> {

    @Override
    public Date deserialize(JsonParser parser, DeserializationContext context) 
            throws IOException, JsonProcessingException {
        String unixTimestamp = parser.getText().trim();
        return new Date(TimeUnit.SECONDS.toMillis(Long.valueOf(unixTimestamp)));
    }
}

在受影响的UnixTimestampDeserializer字段上指定自定义反序列化器(Date):

@JsonDeserialize(using = UnixTimestampDeserializer.class)
private Date updatedAt;

1
投票

我有这个问题,除了我的ZonedDateTime对象转到unix-timestamps(秒),我需要它们在毫秒(在浏览器上初始化JS Date对象)。

实现自定义序列化器/反序列化器对于应该非常简单的事情来说看起来太多了,所以我查看其他地方并发现我可以配置对象映射器以获得所需的结果。

因为我的应用程序已经覆盖了Jersey提供的默认ObjectMapper,所以我只需要禁用SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS

这是我的代码

@Provider
public class RPObjectMapperProvider implements ContextResolver<ObjectMapper> {

    final ObjectMapper defaultObjectMapper;

    public RPObjectMapperProvider() {
        defaultObjectMapper = new ObjectMapper();

        // this turned ZonedDateTime objects to proper seconds timestamps 
        defaultObjectMapper.enable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

        // disable to serialize dates for millis timestamps
        defaultObjectMapper.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);

        // using Java8 date time classes
        defaultObjectMapper.registerModule(new JavaTimeModule());
    }

    @Override
    public ObjectMapper getContext(Class<?> type) {
        return defaultObjectMapper;
    }
}

就是这样

© www.soinside.com 2019 - 2024. All rights reserved.