Jackson LocalDate несуществующая дата - PullRequest
0 голосов
/ 05 сентября 2018

Рассмотрим следующий пример класса:

public class TheDto {
    @JsonFormat(shape = Shape.STRING, pattern = "yyMMdd", lenient = OptBoolean.FALSE)
    private Date date;
    @JsonFormat(shape = Shape.STRING, pattern = "yyMMdd", lenient = OptBoolean.FALSE)
    private LocalDate localDate;
}

Для того же ввода поле "180231", date не может быть проанализировано, поскольку 31 февраля. Февраля не существует.
Но localDate преуспевает со значением "180228".
Есть ли способ заставить LocalDate lenient=false строго проверять дату существования?

1 Ответ

0 голосов
/ 05 сентября 2018

Я советую вам по возможности использовать стандарт ISO 8601 , который одобрен RFC 3339 , а также xkcd 1179 :)


Если такой стандарт не подходит для вашего приложения, вы можете создать свой собственный десериализатор, в котором вы указываете свой собственный DateTimeFormatter с ResolverStyle, который может быть LENIENT, SMART или STRICT:

public class CustomLocalDateDeserializer extends JsonDeserializer<LocalDate> {

    private static final DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder()
            .appendPattern("yyMMdd")
            .parseDefaulting(ChronoField.ERA, 1)
            .toFormatter()
            .withChronology(IsoChronology.INSTANCE)
            .withResolverStyle(ResolverStyle.STRICT); // Also can be LENIENT or SMART

    @Override
    public LocalDate deserialize(JsonParser p,
                                 DeserializationContext ctxt) throws IOException {

        String value = p.getValueAsString();
        return LocalDate.parse(value, FORMATTER);
    }
}

А затем используйте его следующим образом:

public class Foo {

    @JsonDeserialize(using = CustomLocalDateDeserializer.class)
    private LocalDate date;

    // Getters and setters
}
String json = "{\"date\":\"180231\"}";

ObjectMapper mapper = new ObjectMapper();
Foo foo = mapper.readValue(json, Foo.class);

Рассмотрим yyMMdd в качестве формата даты и 180231 в качестве ввода. У вас будут разные результаты в соответствии с ResolverStyle:

  • LENIENT: значение date будет 2018-03-03.
  • SMART: значение date будет 2018-02-28.
  • STRICT: будет сгенерировано исключение: Invalid date 'FEBRUARY 31'.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...