'Getting conversion issue after migrating jackson-databind from 2.11.4 to 2.12.13.2
We have recently migrated jackson-databind from 3.11.4 to 3.12.13.2 version and springframework from 5.2.19.RELEASE to 5.2.22.RELEASE. after the migration we see below exception
java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type java.time.Instant
not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling (
To fix the issue i have added below code
mapper = new ObjectMapper();
mapper.registerModule(new Jdk8Module());
mapper.registerModule(new JavaTimeModule());
which fixed the issue, but i see conversation error now INSTANT type conversation.
expected is "myTime":{"epochSecond":1627413300,"nano":0}
but it is coming as "myTime":1.6274133E9
error : Reason is: Expected a OBJECT, instead got NUMBER for key myTime
working code with older version
pom dependencies -
jackson-databind - 2.11.4 jackson-datatype-jsr310 - 2.11.4
sample code
public class ObjectMapperTest {
public static void main(String[] args) {
try{
ObjectMapper o = new ObjectMapper();
Message message = new Message();
System.out.println(message);
String s2= o.writeValueAsString(message);
System.out.println(s2);
JsonNode i3= o.readTree(s2);
System.out.println(i3);
} catch (Exception e) {
e.printStackTrace();
}
}
static class Message
{
private String source;
@JsonFormat(shape = JsonFormat.Shape.NUMBER, timezone = "UTC")
private Instant timestamp = Instant.now();
@Override
public String toString() {
return "Message [source=" + source + ", timestamp=" + timestamp + "]";
}
}
}
output
Message [source=null, timestamp=2022-05-06T12:28:49.004Z]
{"timestamp":{"epochSecond":1651840129,"nano":4000000}}
{"timestamp":{"epochSecond":1651840129,"nano":4000000}}
Sample code after version upgrade
pom depedencies
jackson-databind - 2.13.2.1 jackson-datatype-jsr310 - 2.13.2
code changes
just add below lines to the above code
ObjectMapper o = new ObjectMapper();
o.registerModule(new JavaTimeModule());
output
Message [source=null, timestamp=2022-05-06T12:28:49.004Z]
{"timestamp":1651839918.691000000}
{"timestamp":1.651839918691E9}
Expected output
Message [source=null, timestamp=2022-05-06T12:28:49.004Z]
{"timestamp":{"epochSecond":1651840129,"nano":4000000}}
{"timestamp":{"epochSecond":1651840129,"nano":4000000}}
Solution 1:[1]
I am able to resolve the issue by creating a custom instant serializer and registering it with JavaTimeModule
public class EpochSecondInstantSerializer extends JsonSerializer {
@Override
public Class<Instant> handledType() {
return Instant.class;
}
@Override
public void serialize(Instant instant, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartObject();
jsonGenerator.writeNumberField("epochSecond", instant.getEpochSecond());
jsonGenerator.writeNumberField("nano", instant.getNano());
jsonGenerator.writeEndObject();
}
}
then registering with JavaTimeModule ObjectMapper mapper = new ObjectMapper().registerModule( new JavaTimeModule().addSerializer(new EpochSecondInstantSerializer()));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | StarFish |