Jackson 升级到 2.15.3 后尝试使用记录时出现“没有基于委托或基于属性的创建者”错误

问题描述 投票:0回答:1

下面的代码在 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 的哪些变化导致了这个吗?

java jackson
1个回答
0
投票

该问题已在 Jackson GitHub channel

中讨论过

2.15 中的行为发生了变化,已在 2.16 中恢复。

以下是相关帖子

我认为 2.16.1 的行为毕竟是我们想要的。棘手的问题是。记录的规范构造函数是自然的选择,因为记录没有默认的无参数构造函数(除了极少数无字段记录的情况)。 所以我之前可能说错了。

现在回想起来,我认为您应该是安全的,即使没有自动检测,也可以找到记录的规范构造函数。正如您所指出的,这部分是因为直到 2.14 为止它总是被检测到。

我们没有计划在 2.16.x 或更高版本的 2.x 中更改此行为

对于造成混乱表示歉意。

© www.soinside.com 2019 - 2024. All rights reserved.