杰克逊LocalDate不存在的日期

时间:2018-09-05 08:41:04

标签: java jackson

请考虑以下示例类:

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。2月不存在。
但是,localDate的成功值为“ 180228”。
有没有一种方法可以强制执行LocalDate lenient=false,以严格验证日期是否存在?

1 个答案:

答案 0 :(得分:1)

我建议您尽可能使用ISO 8601标准,该标准已得到RFC 3339xkcd 1179的认可:)


如果该标准不是您的应用程序的选择,则可以创建自己的解串器,在其中用DateTimeFormatter指定自己的ResolverStyle,可以是LENIENT,{{3 }}或SMART

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作为输入。根据{{​​3}},您将获得不同的结果:

  • STRICTdate的值为2018-03-03
  • ResolverStyledate的值为2018-02-28
  • LENIENT:将引发异常:Invalid date 'FEBRUARY 31'