Spring Boot对ZonedDateTime不使用自定义反序列化器

时间:2018-07-24 11:25:32

标签: java spring spring-boot jackson deserialization

我正在尝试设置我的Spring Boot配置以使用我的自定义 serializer deserializer。

反序列化器代码

public class CustomZonedDateTimeDeserializer extends JsonDeserializer<ZonedDateTime> {

    @Override
    public ZonedDateTime deserialize(JsonParser jsonParser, DeserializationContext context)
            throws IOException, JsonProcessingException {
        ObjectCodec oc = jsonParser.getCodec();
        TextNode node = (TextNode) oc.readTree(jsonParser);
        String dateString = node.textValue();
        return ZonedDateTime.parse(dateString, CustomZonedDateTimeSerializer.formatter);
    }

@Override
public Class<?> handledType() {
    return ZonedDateTime.class;
}

}

序列化器代码

public class CustomZonedDateTimeSerializer extends JsonSerializer<ZonedDateTime> {

    @Override
    public Class<ZonedDateTime> handledType() {
        return ZonedDateTime.class;
    }

    public final static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssZ");

    @Override
    public void serialize(ZonedDateTime date, JsonGenerator generator, SerializerProvider provider)
            throws IOException, JsonProcessingException {
        final String dateString = date.format(formatter);
        generator.writeString(dateString);

    }

}

这是我的配置

@Configuration
public class JacksonConfiguration {

    @Autowired
    Jackson2ObjectMapperBuilder jacksonBuilder;

    @PostConstruct
    public void configureJackson() {

        final CustomZonedDateTimeSerializer serializer = new CustomZonedDateTimeSerializer();
        jacksonBuilder.serializers(serializer);

        final CustomZonedDateTimeDeserializer deserializer = new CustomZonedDateTimeDeserializer();
        jacksonBuilder.deserializers(deserializer);
    }

}

我正在创建一个REST API,因此我在控制器中使用了它:

@RequestMapping(value = "date", method = { RequestMethod.GET })
@ApiOperation(value = "", notes = "")
public ResponseWrapper<String> testDATE(
        @RequestParam @ApiParam(value = "", required = true) ZonedDateTime date) {
    System.out.println(date.toString());
    return new ResponseWrapper<String>(date.toString());
}

到目前为止,我已经尝试过: 创建一个自定义模块,并将其作为@Bean添加到配置中,将序列化器和反序列化器添加到配置中的jackonBuilder对象中,类似于此example

中的代码

我错过了什么还是做错了什么? 每次尝试时,都会出现以下错误:

  

“无法将类型'java.lang.String'的值转换为所需的类型   'java.time.ZonedDateTime';嵌套异常为   org.springframework.core.convert.ConversionFailedException:失败   从类型[java.lang.String]转换为类型   [@ org.springframework.web.bind.annotation.RequestParam   @ io.swagger.annotations.ApiParam java.time.ZonedDateTime]作为值   '2018-07-10T00:00:00 + 0000';嵌套异常为   java.lang.IllegalArgumentException:尝试解析值失败   [2018-07-10T00:00:00 + 0000]“

enter image description here

我每次发送以下值:2018-07-10T00:00:00 + 0000,该值甚至没有到达我有断点的解串器。

2 个答案:

答案 0 :(得分:1)

将此bean添加到您的配置类中:

@Bean
public Jackson2ObjectMapperBuilder configureObjectMapper() {
    Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
    final CustomZonedDateTimeSerializer serializer = new CustomZonedDateTimeSerializer();
    builder.serializers(serializer);

    final CustomZonedDateTimeDeserializer deserializer = new CustomZonedDateTimeDeserializer();
    builder.deserializers(deserializer);
    return builder;
}

答案 1 :(得分:0)

似乎我无法在 GET 请求中发送ZonedDateTime。更改为 POST 后,Spring便能够自动解析日期。

我只添加了 spring.jackson.deserialization.adjust_dates_to_context_time_zone = true ,因此它考虑了时区。

如果有人要使用GET发送,则必须发送一个字符串并进行解析,而不是将ZonedDateTime定义为参数。