How do I deserialize timestamps that are in seconds with Jackson?

后端 未结 4 1137
后悔当初
后悔当初 2020-11-29 08:29

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

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

Asking Jackson to de

相关标签:
4条回答
  • 2020-11-29 08:30

    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;
    
    0 讨论(0)
  • 2020-11-29 08:40
    @JsonFormat(shape=JsonFormat.Shape.STRING, pattern="s")
    public Date timestamp;
    

    edit: vivek-kothari suggestion

    @JsonFormat(shape=JsonFormat.Shape.NUMBER, pattern="s")
    public Timestamp timestamp;
    
    0 讨论(0)
  • 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
        }
    }
    
    0 讨论(0)
  • 2020-11-29 08:55

    I had this exact issue, except my ZonedDateTime objects got turned to unix-timestamps (seconds) and I needed them in milliseconds (to initialize JS Date objects on the browser).

    Implementing a custom serializer/deserializer looked like too much work for something that should be pretty straightforward, so I looked elsewhere and found that I can just configure the object mapper for the desired result.

    Because my application already overrides the default ObjectMapper provided by Jersey, I just had to disable SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS.

    Here's my code

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

    And that's it

    0 讨论(0)
提交回复
热议问题