ジャックソンのStringでjodaを回るDateTimeのピット記録

9828 ワード

希-望円満-背景:最近会社は秒殺活動をしていて、ちょうど私がした活動時間にそれを処理しています.そのうちの1つはフロントのjsonをJacksonを通じてjoda.DateTimeに変更する責任があるが、その間に問題が発生した.
問題の説明"2019-10-24 00:00:00"をJackson経由で直接DateTimeに変更すると、次のようなエラーが発生します.
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `org.joda.time.DateTime` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('2019-10-24 00:00:00'); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `org.joda.time.DateTime` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('2019-10-24 00:00:00')
 at ...
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `org.joda.time.DateTime` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('2019-10-24 00:00:00')
 at ...

コンストラクタに問題があったと感じ、jackson-corejackson-databindjackson-datatype-jodaの3つのパッケージを導入した後、同時に、application.propertiesにtime-format:spring.jackson.joda-date-time-format="yyyy-MM-dd HH:mm:ss"を配置した後、再稼働し、依然として問題があることを発見しました:
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Invalid format: "2019-10-24 00:00:00" is malformed at " 00:00:00"; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Invalid format: "2019-10-24 00:00:00" is malformed at " 00:00:00" (through reference chain: com.savannah.service.model.PromoDTO["startDate"])
	at ...
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Invalid format: "2019-10-24 00:00:00" is malformed at " 00:00:00" (through reference chain: com.savannah.service.model.PromoDTO["startDate"])
	at ...
Caused by: java.lang.IllegalArgumentException: Invalid format: "2019-10-24 00:00:00" is malformed at " 00:00:00"
	at...

フォーマット変換が正しくないことがわかりますが、長い間フォーマットを正しく変換する方法が見つかりませんでした.
発生原因
Jacksonが内蔵しているjoda.DateTimeを変換しない方法では、3番目のJarパッケージまたはカスタムシーケンス化/逆シーケンス化によってこの問題を解決する必要があることが容易にわかります.
ソリューション
  • カスタムJacksonでのエンティティークラスのシーケンス化と逆シーケンス化方法:
  • public class CustomDateSerializer extends JsonSerializer<DateTime> {
    
        private static DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
    
        @Override
        public void serialize(DateTime value, JsonGenerator gen, SerializerProvider arg2) throws IOException {
            gen.writeString(formatter.print(value));
        }
    }
    public class CustomDateDeserializer extends JsonDeserializer<DateTime> {
    
        private static DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
    
        @Override
        public DateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
            JsonNode node = jsonParser.getCodec().readTree(jsonParser);
            String s = node.asText();
            return DateTime.parse(s, formatter);
        }
    }
    
  • DateTimeタイプのフィールドに注記を追加:
  • 	/**
         *       
         */
        @JsonSerialize(using = CustomDateSerializer.class)
        @JsonDeserialize(using = CustomDateDeserializer.class)
        private DateTime startDate;
    
        /**
         *         
         */
        @JsonSerialize(using = CustomDateSerializer.class)
        @JsonDeserialize(using = CustomDateDeserializer.class)
        private DateTime endDate;
    

    これでほぼ完成し、参加してみることもできます.
    <dependency>
          <groupId>com.fasterxml.jackson.datatypegroupId>
          <artifactId>jackson-datatype-jodaartifactId>
          <version>2.9.8version>
    dependency>
    

    このjarパッケージは、逆シーケンス化の結果が違いますよ