Customize how Jackson performs LocalDate parsing

Ĵackson is the most widely used ĴSON parser / generator library in the Java ecosystem, and is a default dependency of Spring Boot.

Dates come in many formats and that’s a problem when we want to go from a date field in JSON to a Java Localdate object.

Girl at chalkboard

What does that mean?

For example, in GearBuddy, my outdoor gear management application, you can track when you bought each piece of gear with the purchaseDate field. This is a date without a time, and the idea is that you put in May 24, 1995 or whenever you bought it.

JSON does not have a "date" type, so you can pass a string for the date in the request. In GearBuddy, the request is as follows (note the last field):

{
    "type": "Tent",
    "model": "Montana",
    "brand": "Coleman",
    "size": "8-person",
    "purchaseDate": "10/21/2016"
}

The only problem is that if the request is sent to the application, it will cause the following error:

{
    "timestamp": "2019-06-07T21:19:47.500+0000",
    "status": 400,
    "error": "Bad Request",
    "message": "JSON parse error: Cannot deserialize value of type `java.time.LocalDate` from String \"10/21/2016\": Failed to deserialize java.time.LocalDate: (java.time.format.DateTimeParseException) Text '10/21/2016' could not be parsed at index 0; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.LocalDate` from String \"10/21/2016\": Failed to deserialize java.time.LocalDate: (java.time.format.DateTimeParseException) Text '10/21/2016' could not be parsed at index 0\n at [Source: (PushbackInputStream); line: 6, column: 18] (through reference chain: org.gearbuddy.requests.PostGearRequestBody[\"purchaseDate\"])",
    "path": "/gear"
}

Domestic quarrel. From Barber, John W. The Handbook of Illustrated Proverbs (New York, NY: George F. Tuttle, 1857)

Why that won’t work

The error message cannot fully explain why the application is angry, but this is because the date string passed ("October 21, 2016") is not in a format that Jackson can parse. For some people, this may be strange because "10/21/2016" is a common way to write dates in the United States.

But Jackson only knows the international format of yyyy-MM-dd by default, which means that if we change the request to "2016-10-21", the request will work normally.

This may not help users of our application.

So Change it

You can (of course!) Change the format that Jackson can understand.

The way to do this is to add the @JsonFormat annotation in the relevant field in the Java object.

@JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
public PostGearRequestBody(
        @JsonProperty("type") String type, 
        @JsonProperty("brand") String brand,
        @JsonProperty("model") String model, 
        @JsonProperty("color") String color,
        @JsonProperty("size") String size, 
        @JsonProperty("purchasePlace") String purchasePlace,
        @JsonProperty("purchasePrice") String purchasePrice,
        @JsonProperty("purchaseDate") @JsonFormat(pattern = "MM/dd/yyyy") LocalDate purchaseDate,
        @JsonProperty("warranty") String warranty) {
    // ... etc
}

Please note that the penultimate method parameter has both @JsonProperty annotation and JsonFormat annotation:

// ...
@JsonProperty("purchaseDate") @JsonFormat(pattern = "MM/dd/yyyy") LocalDate purchaseDate,
// ...

You can read more about @JsonFormat in the Jackson API documentation.

After making this change and compiling the application, requests with the date format "10/21/2016" can now run successfully!

ñote: Originally published at code.scottshipp.com.

from: https://dev.to//scottshipp/customize-how-jackson-does-localdate-parsing-2hc5

Published 0 original articles · liked 0 · visits 659

Guess you like

Origin blog.csdn.net/cunxiedian8614/article/details/105691025