programing

잭슨과 함께 몇 초 만에 타임스탬프를 역직렬화하려면 어떻게 해야 하나요?

mytipbox 2023. 2. 22. 21:26
반응형

잭슨과 함께 몇 초 만에 타임스탬프를 역직렬화하려면 어떻게 해야 하나요?

타임스탬프(즉, Unix 타임스탬프)가 초단위로 표시되는 JSON이 있습니다.

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

잭슨에게 타임스탬프의 DateTime 필드가 있는 객체로 이것을 역직렬화하도록 요구하면1970-01-17T01:11:25.983Z잭슨이 밀리초 단위로 가정하고 있기 때문에 이 에폭 직후의 시간.JSON을 분해하고 0을 추가하는 것 외에 어떻게 잭슨에게 의 타임스탬프를 이해시킬 수 있을까요?

타임스탬프를 초단위로 처리하는 커스텀 디시리얼라이저를 작성했습니다(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
    }
}
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="s")
public Date timestamp;

편집: vivek-kothari 제안

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

Java SE를 사용하는 @DrewStephens의 접근법과 매우 유사합니다.TimeUnitAPI(에서 도입)JDK1.5plain String 연결 대신 (논쟁적으로) 조금 더 깔끔하고 표현력이 뛰어납니다.

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;

ZonedDateTime 객체가 unix-timestamps(초)로 변환되어 (브라우저에서 JS Date 객체를 초기화하기 위해) 밀리초 이내에 필요한 것을 제외하고, 이 문제가 있었습니다.

커스텀 시리얼라이저/디시리얼라이저를 실장하는 것은 매우 간단한 작업이라고 생각되기 때문에 다른 곳을 찾아보니 오브젝트 매퍼를 원하는 결과로 설정할 수 있습니다.

응용 프로그램은 이미 Jersey에서 제공하는 기본 ObjectMapper보다 우선하기 때문에 사용하지 않도록 설정해야 했습니다.

여기 제 코드가 있습니다.

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

그리고 이것이 마지막입니다.

언급URL : https://stackoverflow.com/questions/20635698/how-do-i-deserialize-timestamps-that-are-in-seconds-with-jackson

반응형