java 无法构造-Jackson的示例

cyvaqqii  于 2023-03-06  发布在  Java
关注(0)|答案(9)|浏览(159)

我正在使用Jackson,遇到了一些问题,当我尝试反序列化对象时,出现以下错误:

com.fasterxml.jackson.databind.JsonMappingException: 
    Can not construct instance of net.MyAbstractClass, 
    problem: abstract types either need to be mapped to concrete types, 
        have custom deserializer, or be instantiated with additional type information

我在属性中遇到问题:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_OBJECT, property = "@id")
@JsonSubTypes({ @JsonSubTypes.Type(value = MyAbstractClass.class, name = "MyAbstractClass") })
@ManyToOne
private MyAbstractClass object;

有人能帮帮我吗?

erhoui1w

erhoui1w1#

反序列化时,您需要使用具体类而不是抽象类。如果抽象类有多个实现,则在这种情况下,您可以按如下方式使用它-

@JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
    @JsonSubTypes({ 
      @Type(value = Bike.class, name = "bike"), 
      @Type(value = Auto.class, name = "auto"), 
      @Type(value = Car.class, name = "car")
    })
    public abstract class Vehicle {
        // fields, constructors, getters, setters
    }
rur96b6h

rur96b6h2#

您的@JsonSubTypes声明没有意义:它需要列出实现(子)类,而不是类本身(这将是毫无意义的)。所以你需要修改该条目以列出子类;或者使用一些其它机制来注册子类(SimpleModule具有类似于addAbstractTypeMapping的内容)。

tgabmvqs

tgabmvqs3#

在你的具体例子中,问题在于你没有正确地使用这个结构:

@JsonSubTypes({ @JsonSubTypes.Type(value = MyAbstractClass.class, name = "MyAbstractClass") })

@JsonSubTypes.Type应该包含抽象类的实际非抽象子类型。
因此,如果您有:
abstract class Parent和具体子类
Ch1 extends ParentCh2 extends Parent
然后,注解应如下所示:

@JsonSubTypes({ 
          @JsonSubTypes.Type(value = Ch1.class, name = "ch1"),
          @JsonSubTypes.Type(value = Ch2.class, name = "ch2")
})

这里name应该与您的“discriminator”值匹配:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, 
include = JsonTypeInfo.As.WRAPPER_OBJECT, 
property = "type")

property字段中,它等于type。因此type将是键,而您在name中设置的值将是值。
因此,当json字符串出现时,如果它具有以下形式:

{
 "type": "ch1",
 "other":"fields"
}

Jackson会自动将其转换为Ch1类。
如果您发送此消息:

{
 "type": "ch2",
 "other":"fields"
}

您将获得一个Ch2示例。

fzsnzjdm

fzsnzjdm4#

对于我来说,没有为我尝试使用的POJO定义默认构造函数。创建默认构造函数修复了它。

public class TeamCode {

    @Expose
    private String value;

    public String getValue() {
        return value;
    }

    **public TeamCode() {
    }**

    public TeamCode(String value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "TeamCode{" +
                "value='" + value + '\'' +
                '}';
    }

    public void setValue(String value) {
        this.value = value;
    }

}
9vw9lbht

9vw9lbht5#

使用@JsonDeserialize(contentAs= ConcreteCLass.class)

tcbh2hod

tcbh2hod6#

使用lombok注解。

@AllArgsConstructor
@NoArgsConstructor
@Builder
@JsonPropertyOrder({"name", "id"})
public class CreationUser {
    @Builder.Default
    @JsonProperty("name")
    String name = "";

    @Builder.Default
    @JsonProperty("id")
    String id = "";
}
slhcrj9b

slhcrj9b7#

使用lombok我也有同样的问题,我已经尝试过这个来解决

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
92vpleto

92vpleto8#

你不能示例化一个抽象类,Jackson也不能。你应该给予Jackson关于如何用一个具体类型示例化MyAbstractClass的信息。
请在stackoverflow上查看此答案:Jackson JSON library: how to instantiate a class that contains abstract fields
也许还可以参见Jackson Polymorphic Deserialization

du7egjpx

du7egjpx9#

我在单独使用lombok的@Data@Builder注解时遇到了这个问题,我将其替换为:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder

而且它解决了我的问题。

相关问题