将 jackson-databind 从 2.11.4 迁移到 2.12.13.2 后出现转换问题
Getting conversion issue after migrating jackson-databind from 2.11.4 to 2.12.13.2
我们最近将 jackson-databind 从 3.11.4 版本迁移到 3.12.13.2 版本,并将 springframework 从 5.2.19.RELEASE 迁移到 5.2.22.RELEASE。迁移后我们看到下面的异常
java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time 默认不支持类型 java.time.Instant
: 添加模块 "com.fasterxml.jackson.datatype:jackson- datatype-jsr310”启用处理(
为了解决这个问题,我在下面添加了代码
mapper = new ObjectMapper();
mapper.registerModule(new Jdk8Module());
mapper.registerModule(new JavaTimeModule());
这解决了问题,但我现在看到对话错误即时类型对话。
预计是“myTime”:{“epochSecond”:1627413300,“nano”:0}
但它以“myTime”的形式出现:1.6274133E9
错误:原因是:需要一个 OBJECT,却得到了密钥 myTime
的 NUMBER
旧版本的工作代码
pom依赖项-
杰克逊数据绑定 - 2.11.4
杰克逊数据类型 jsr310 - 2.11.4
示例代码
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 + "]";
}
}
}
输出
Message [source=null, timestamp=2022-05-06T12:28:49.004Z]
{"timestamp":{"epochSecond":1651840129,"nano":4000000}}
{"timestamp":{"epochSecond":1651840129,"nano":4000000}}
版本升级后的示例代码
pom 依赖关系
杰克逊数据绑定 - 2.13.2.1
杰克逊数据类型 jsr310 - 2.13.2
代码更改
只需在上面的代码中添加以下行
ObjectMapper o = new ObjectMapper();
o.registerModule(new JavaTimeModule());
输出
Message [source=null, timestamp=2022-05-06T12:28:49.004Z]
{"timestamp":1651839918.691000000}
{"timestamp":1.651839918691E9}
预期输出
Message [source=null, timestamp=2022-05-06T12:28:49.004Z]
{"timestamp":{"epochSecond":1651840129,"nano":4000000}}
{"timestamp":{"epochSecond":1651840129,"nano":4000000}}
我可以通过创建自定义即时序列化程序并将其注册到 JavaTimeModule 来解决问题
public class EpochSecondInstantSerializer 扩展 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();
}
}
然后注册 JavaTimeModule
ObjectMapper 映射器 = new ObjectMapper().registerModule(
new JavaTimeModule().addSerializer(new EpochSecondInstantSerializer()));
我们最近将 jackson-databind 从 3.11.4 版本迁移到 3.12.13.2 版本,并将 springframework 从 5.2.19.RELEASE 迁移到 5.2.22.RELEASE。迁移后我们看到下面的异常
java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time 默认不支持类型 java.time.Instant
: 添加模块 "com.fasterxml.jackson.datatype:jackson- datatype-jsr310”启用处理(
为了解决这个问题,我在下面添加了代码
mapper = new ObjectMapper();
mapper.registerModule(new Jdk8Module());
mapper.registerModule(new JavaTimeModule());
这解决了问题,但我现在看到对话错误即时类型对话。
预计是“myTime”:{“epochSecond”:1627413300,“nano”:0}
但它以“myTime”的形式出现:1.6274133E9
错误:原因是:需要一个 OBJECT,却得到了密钥 myTime
的 NUMBER旧版本的工作代码
pom依赖项-
杰克逊数据绑定 - 2.11.4 杰克逊数据类型 jsr310 - 2.11.4
示例代码
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 + "]";
}
}
}
输出
Message [source=null, timestamp=2022-05-06T12:28:49.004Z]
{"timestamp":{"epochSecond":1651840129,"nano":4000000}}
{"timestamp":{"epochSecond":1651840129,"nano":4000000}}
版本升级后的示例代码
pom 依赖关系
杰克逊数据绑定 - 2.13.2.1 杰克逊数据类型 jsr310 - 2.13.2
代码更改
只需在上面的代码中添加以下行
ObjectMapper o = new ObjectMapper();
o.registerModule(new JavaTimeModule());
输出
Message [source=null, timestamp=2022-05-06T12:28:49.004Z]
{"timestamp":1651839918.691000000}
{"timestamp":1.651839918691E9}
预期输出
Message [source=null, timestamp=2022-05-06T12:28:49.004Z]
{"timestamp":{"epochSecond":1651840129,"nano":4000000}}
{"timestamp":{"epochSecond":1651840129,"nano":4000000}}
我可以通过创建自定义即时序列化程序并将其注册到 JavaTimeModule 来解决问题
public class EpochSecondInstantSerializer 扩展 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();
}
}
然后注册 JavaTimeModule ObjectMapper 映射器 = new ObjectMapper().registerModule( new JavaTimeModule().addSerializer(new EpochSecondInstantSerializer()));