使用杰克逊的 JSON 反序列化:没有找到适合类型的构造函数 - 可以提供默认构造函数或注释构造函数 [重复]

Posted

技术标签:

【中文标题】使用杰克逊的 JSON 反序列化:没有找到适合类型的构造函数 - 可以提供默认构造函数或注释构造函数 [重复]【英文标题】:JSON deserialisation using Jackson: No suitable constructor found for type - providing default constructor or annotate constructor is imposible [duplicate] 【发布时间】:2015-07-16 19:05:15 【问题描述】:

我使用 Jackson ObjectMapper 将对象层次结构序列化为 json String。之后我想反序列化对象。我得到了如下异常。

重要的是 APINewDealArrangementImpl 类层次结构超出了我的更改范围 - 它是外部库的一部分。在这种情况下 我无法实现默认构造函数,也无法使用 @JsonCreator 注释

如何避免“未找到合适的构造函数”异常?是否可以使用一些自定义 TypeResolverBuilder 实现或 Jackson API 中的其他功能来解决这个问题?感谢您的帮助。

org.codehaus.jackson.map.JsonMappingException: No suitable constructor found for type [simple type, class com.tzero.api.transactions.TransactionState]: can not instantiate from JSON object (need to add/enable type information?)
 at [Source: java.io.StringReader@57ac3379; line: 4, column: 5] (through reference chain: com.tzero.api.java.transactions.APINewDealArrangementImpl["state"])
    at org.codehaus.jackson.map.JsonMappingException.from(JsonMappingException.java:163)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObjectUsingNonDefault(BeanDeserializer.java:746)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:683)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
    at org.codehaus.jackson.map.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:299)
    at org.codehaus.jackson.map.deser.SettableBeanProperty$MethodProperty.deserializeAndSet(SettableBeanProperty.java:414)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:697)
    at org.codehaus.jackson.map.deser.BeanDeserializer.deserialize(BeanDeserializer.java:580)
    at org.codehaus.jackson.map.ObjectMapper._readMapAndClose(ObjectMapper.java:2732)
    at org.codehaus.jackson.map.ObjectMapper.readValue(ObjectMapper.java:1863)

【问题讨论】:

这是Jackson Mixins的一个很好的用例 @GarisMSuero 这不是重复的,因为我无法为序列化类实现默认指导。如上所述,原因是我无法修改该类 - 它是封闭源代码。 @peeskillet,谢谢 :) 这完成了工作。 这个问题不是重复的,应该被标记。原始问题假设可以修改对象,而此问题假设对象是第三方且不可更改。 @TylerH 您能否按上述方式从该问题中删除重复标记? 【参考方案1】:

您可以使用“mixin”为不同的类提供注释。这有点奇怪,但非常有用。

@Test
public void mixin_to_specify_creator() throws Exception 
    TargetData target = mapper.addMixIn(TargetData.class, TargetDataMixin.class).reader(TargetData.class)
            .<TargetData> readValue("\"name\":\"the name\", \"description\":\"the description\"");
    assertThat(target.name, equalTo("the name"));
    assertThat(target.description, equalTo("the description"));


public static class TargetData 
    private final String name;
    private final String description;

    public TargetData(String name, String description) 
        this.name = name;
        this.description = description;
    


public static abstract class TargetDataMixin 
    @JsonCreator
    public TargetDataMixin(@JsonProperty("name") String name, @JsonProperty("description") String description) 
    

所以这里TargetData上没有Jackson注解,注解取自TargetDataMixin(完全忽略TargetDataMixin的实现)

【讨论】:

以上是关于使用杰克逊的 JSON 反序列化:没有找到适合类型的构造函数 - 可以提供默认构造函数或注释构造函数 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

杰克逊从JSON中的变量类型反序列化

Jackson ObjectMapper 无法反序列化 POJO,抛出异常:没有找到适合类型 [...] 的构造函数:无法从 JSON 对象实例化

反序列化的改造/杰克逊错误

反序列化杰克逊中同名但不同类型的属性?

JSON杰克逊序列化反序列化列表列表

无法使用杰克逊反序列化包含 2 个具有相同 ID 的对象的 Json