How do I deserialize timestamps that are in second

2019-01-11 12:55发布

问题:

I've got some JSON that has timestamps in seconds (i.e. a Unix timestamp):

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

Asking Jackson to deserialize this into an object with a DateTime field for the timestamp results in 1970-01-17T01:11:25.983Z, a time shortly after the epoch because Jackson is assuming it to be in milliseconds. Aside from ripping apart the JSON and adding some zeros, how might I get Jackson to understand the seconds timestamp?

回答1:

I wrote a custom deserializer to handle timestamps in seconds (Groovy syntax).

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

And then I annotated my POGO to use that for the timestamp:

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

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


回答2:

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

edit: vivek-kothari suggestion

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


回答3:

A very similar approach to that of @DrewStephens's which uses the Java SE TimeUnit API (introduced in JDK1.5) instead of plain String concatenation and is thus (arguably) a little bit cleaner and more expressive:

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

Specifying your custom deserializer (UnixTimestampDeserializer) on the affected Date field(s):

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