com.fasterxml.jackson.databind.JsonMappingException:java.util.Optional 不能转换为 java.time.LocalDate
Posted
技术标签:
【中文标题】com.fasterxml.jackson.databind.JsonMappingException:java.util.Optional 不能转换为 java.time.LocalDate【英文标题】:com.fasterxml.jackson.databind.JsonMappingException: java.util.Optional cannot be cast to java.time.LocalDate 【发布时间】:2021-12-22 19:09:35 【问题描述】:技术栈: Spring Boot 1.5.8、Java 8、JUnit 4、jackson 2.13.0、jackson-datatype-jdk8 2.9.6
我正在为涉及 JSON 和 POJO 之间的序列化和反序列化的服务编写单元测试。当我尝试使用 com.fasterxml.jackson.databind.ObjectMapper 将 java 对象转换为 json 时,它给了我以下错误,
com.fasterxml.jackson.databind.JsonMappingException: java.util.Optional cannot be cast to java.time.LocalDate (through reference chain: com.ctm.common.request.application.ApplicationRequest["payload"]->com.ctm.healthapply.model.request.HealthApplicationRequest["applicants"]->com.ctm.healthapply.model.request.application.ApplicationGroup["governmentRebateAcknowledgement"]->com.ctm.healthapply.model.request.application.GovernmentRebate.GovernmentRebateAcknowledgement["declarationDate"])
完整的跟踪,
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:392)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:351)
at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:316)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:782)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.ser.std.ReferenceTypeSerializer.serialize(ReferenceTypeSerializer.java:386)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:178)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
at com.fasterxml.jackson.databind.ObjectMapper._writeValueAndClose(ObjectMapper.java:4569)
at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:3822)
at com.ctm.healthapply.service.RequestResponseTransformServiceImplTest.testAUFApplicationFamily(RequestResponseTransformServiceImplTest.java:69)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: java.lang.ClassCastException: java.util.Optional cannot be cast to java.time.LocalDate
at com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer.serialize(LocalDateSerializer.java:36)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:774)
... 39 more
来自我的 pom.xml,
<properties>
<jackson.version>2.13.0</jackson.version>
<jackson-datatype-jdk8.version>2.9.6</jackson-datatype-jdk8.version>
</properties>
<!-- JSON serialization -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>$jackson.version</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>$jackson.version</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>$jackson.version</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
<version>$jackson-datatype-jdk8.version</version>
</dependency>
有问题的领域和它的吸气剂,
@JsonSerialize(
using = LocalDateSerializer.class
)
private LocalDate declarationDate;
public Optional<LocalDate> getDeclarationDate()
return Optional.ofNullable(this.declarationDate);
尝试writeValueAsString时出现错误,
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new Jdk8Module());
String requestAsJson = mapper.writeValueAsString(healthModelApplyRequest);
请帮助解决这个问题。
【问题讨论】:
您正在混合使用不同的杰克逊版本 2.13 和 2.9,这是等待发生的麻烦。另外我不相信 jackson 2.13 与 Spring Boot 1.5 兼容。 避免随意使用版本。这就是 Spring Boot 有用的原因,因为它保证了不同组件的版本实际上是兼容的。 Jackson 是 Spring Boot Starter Web 的传递依赖项,因此您确实需要明确定义版本。 已经尝试过从 2.8.10 到最新的 2.13.0 的不同版本。同样的问题 【参考方案1】:不要尝试不同的版本,只是不要向 Jackson 依赖项添加任何版本属性(spring-boot-starter-parent
已经定义了这样的版本)。请尝试以下操作:
<!-- JSON serialization -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
【讨论】:
以上是关于com.fasterxml.jackson.databind.JsonMappingException:java.util.Optional 不能转换为 java.time.LocalDate的主要内容,如果未能解决你的问题,请参考以下文章