下面的代码在 Jackson 2.15.3 中抛出错误,但在 2.14.3 中也运行良好。
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
class JacksonTest {
@Test
void test() {
var str = """
{"id" : "test-rest"}
""";
var objectMapper = new BaseObjectMapper();
try {
System.out.println(objectMapper.readValue(str, TestResp.class));
} catch (Exception e) {
e.printStackTrace();
Assertions.fail();
}
}
record TestResp(String id) {}
private static class BaseObjectMapper extends ObjectMapper {
BaseObjectMapper() {
setVisibility(
getSerializationConfig()
.getDefaultVisibilityChecker()
.withFieldVisibility(JsonAutoDetect.Visibility.ANY)
.withGetterVisibility(JsonAutoDetect.Visibility.NONE)
.withIsGetterVisibility(JsonAutoDetect.Visibility.NONE)
.withSetterVisibility(JsonAutoDetect.Visibility.NONE)
.withCreatorVisibility(JsonAutoDetect.Visibility.NONE))
.setSerializationInclusion(Include.NON_NULL);
}
}
}
我在 Jackson 2.15.3 中遇到的异常如下
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.spotnana.obt.master.apis.auth.authentication.JacksonTest$TestResp` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (String)" {"id" : "test-rest"}
"; line: 1, column: 4]
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1915)
at com.fasterxml.jackson.databind.DatabindContext.reportBadDefinition(DatabindContext.java:414)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1360)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1424)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:352)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:185)
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4825)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3772)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3740)
at com.spotnana.obt.master.apis.auth.authentication.JacksonTest.test(JacksonTest.java:19)
Jackson 2.15.3 是否会出现这种情况?有人可以告诉我 Jackson 2.15.3 的哪些变化导致了这个吗?
该问题已在 Jackson GitHub channel
中讨论过2.15 中的行为发生了变化,已在 2.16 中恢复。
以下是相关帖子我认为 2.16.1 的行为毕竟是我们想要的。棘手的问题是。记录的规范构造函数是自然的选择,因为记录没有默认的无参数构造函数(除了极少数无字段记录的情况)。 所以我之前可能说错了。
现在回想起来,我认为您应该是安全的,即使没有自动检测,也可以找到记录的规范构造函数。正如您所指出的,这部分是因为直到 2.14 为止它总是被检测到。
我们没有计划在 2.16.x 或更高版本的 2.x 中更改此行为
对于造成混乱表示歉意。