首页 > 解决方案 > Spring Boot 中 OffsetDateTime 的序列化器/反序列化器

问题描述

我在 Spring Boot v1.5.14.RELEASE 应用程序中为 OffsetDateTime 创建了一个序列化器/反序列化器。首先我创建一个自定义约束注解:

@Primary
    @Bean
    public ObjectMapper objectMapper() {

        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(OffsetDateTime.class, new JsonSerializer<OffsetDateTime>() {
            @Override
            public void serialize(OffsetDateTime offsetDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
                jsonGenerator.writeString(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(offsetDateTime));
            }
        });

        simpleModule.addDeserializer(OffsetDateTime.class, new  JsonDeserializer<OffsetDateTime>() {
            @Override
            public OffsetDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
                return DateUtils.convertToOffsetDateTime(jsonParser.getValueAsString());
            }
        });

        objectMapper.registerModule(simpleModule);

        return objectMapper;
    }

在响应中,我看到了正确格式化的值,但是在请求时我收到了这个错误

Failed to convert property value of type 'java.lang.String' to required type 'java.time.OffsetDateTime' for property 'fromDate'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@com.fasterxml.jackson.annotation.JsonFormat java.time.OffsetDateTime] for value '2019-01-01'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2019-01-01]]

public static OffsetDateTime convertToOffsetDateTime (String date) {
        ZoneId zoneId = ZoneId.of(DateFormat.TIME_ZONE_ID);
        ZoneOffset currentOffsetForMyZone = zoneId.getRules().getOffset(Instant.now());
        return OffsetDateTime.of( parseLocalDate(date),LocalTime.NOON, currentOffsetForMyZone);
    }

而且我认为甚至没有调用解串器,因为我添加了它来抛出异常,但没有抛出异常......

        public OffsetDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
            int m = 9 /0 ;
            return DateUtils.convertToOffsetDateTime(jsonParser.getValueAsString());
        }


public static LocalDate parseLocalDate(String  strDate) {
        return LocalDate.parse(strDate, DateFormat.DATE_FORMATTER);
    }

和豆子:

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class HotelData {

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
    private OffsetDateTime fromDate;
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
    private OffsetDateTime toDate;

}

public final class DateFormat {

    public static final String DATE_PATTERN = "yyyy-MM-dd";
    public static final String TIME_ZONE_ID = "Africa/Brazzaville";
    public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter
            .ofPattern(DATE_PATTERN)
            .withZone(ZoneId.of(TIME_ZONE_ID));

    private DateFormat(){}
}

问题在于测试:

 mockMvc.perform(get("/hotel")
                .param("hotelId", "1338767")
                .param("fromDate", "2019-01-01")
                .param("toDate", "2019-05-21")
                .contentType(APPLICATION_JSON))
                .andDo(print())
                .andExpect(status().isOk());

标签: javajsonspringspring-bootjackson

解决方案


推荐阅读