In Jackson 2.11 was change about LocalDataTime format during serialization. I have problem with deserialization. I've found solution to override configuration from objectMapper like bellow:
@Configuration
public class AppConfig {
@Bean
public ObjectMapper objectMapper()
{
ObjectMapper mapper = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
mapper.registerModule(javaTimeModule);
return mapper;
}
but I've still problem with deserialization json string to java model:
@Data
public class CustomLocalDataTime {
//@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSxxx") <- not working
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS") // <- not working
// @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", shape = JsonFormat.Shape.STRING) <- not working
private LocalDateTime date;
}
So I am receiving from some response localdatatime in format example: 2022-04-05T05:00:00.000 00:00 and during deserialization I am still getting error:
com.fasterxml.jackson.databind.exc.InvalidFormatException:
Cannot deserialize value of type `java.time.LocalDateTime`
from String "2022-04-05T05:00:00.000 00:00": Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException) Text '2022-04-05T05:00:00.000 00:00'
could not be parsed, unparsed text found at index 23
at [Source: (String)"{"date":"2022-04-05T05:00:00.000 00:00"}"; line: 1, column: 9]
I am receiving this error by reproducing this like that:
@PostConstruct
public void customDeserializeTest() {
String content =
"{\"date\":\"2022-04-05T05:00:00.000 00:00\"}";
try {
CustomLocalDataTime customLocalDataTime = objectMapper.readValue(content, CustomLocalDataTime.class);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
I've tried also to add: com.fasterxml.jackson.databind.annotation.
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
but that also does not work.
Thank you very much in advance for any guidance.
CodePudding user response:
Wrong data type
As others commented, you are using the wrong data types.
The LocalDateTime
class purposely lacks any concept of time zone or offset-from-UTC. So this class cannot represent a moment, a specific point on the timeline. This class represents only a date and time-of-day, but we have no idea whether that date and time-of-day is intended for Tokyo Japan, Toulouse France, or Toledo Ohio US.
So the LocalDateTime
class does not fit your inputs.
The string inputs:
2022-04-05T05:00:00.000 00:00
2022-04-05T05:00:00.000Z
… both represent a moment as seen in UTC, with an offset from UTC of zero hours-minutes-seconds. The Z
on the end of the second one is a standard ISO 8601 abbreviation of 00:00
, and is pronounced “Zulu”.
Instant
& OffsetDateTime
You can parse both such inputs as Instant
objects or as more flexible OffsetDateTime
objects.
These input strings use standard ISO 8601 formats. The java.time classes use these formats by default when parsing/generating. So no need to specify a formatting pattern.
Instant instant = Instant.parse( "2022-04-05T05:00:00.000 00:00" ) ;
Instant instant2 = Instant.parse( "2022-04-05T05:00:00.000Z" ) ;
OffsetDateTime odt = OffsetDateTime.parse( "2022-04-05T05:00:00.000 00:00" ) ;
OffsetDateTime odt2 = OffsetDateTime.parse( "2022-04-05T05:00:00.000Z" ) ;
See this code run live at IdeOne.com.
instant: 2022-04-05T05:00:00Z
instant2: 2022-04-05T05:00:00Z
odt: 2022-04-05T05:00Z
odt2: 2022-04-05T05:00Z
One Comment mentioned using ZonedDateTime
. That would be ill-advised. Time zones have names in format of Continent/Region
such as Europe/Paris
or Pacific/Auckland
. Your inputs have only offsets, not time zones. So ZonedDateTime
would be misleading and confusing here.
An offset is merely a number of hours-minutes-seconds ahead or behind the prime meridian of UTC. A time zone is much more. A time zone is a named history of the past, present, and future changes to the offset used by the people of a particular region.