java - jackson 抛出 JsonMappingException 无法构造实例

标签 java json jackson jackson-databind

//界面

public interface NotificationPayload {
}

//类实现接口(interface)

public ClassA implements NotificationPayload {...}
public ClassB implements NotificationPayload {...}
...
public ClassX implements NotificationPayload {...}

//发送消息

public class Notification<T extends NotificationPayload> {
    private T data; //T may be ClassA/ClassB/ClassC.../ClassX
    ...
}

当我收到 json 格式的消息时,我想使用 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper) 将其再次转换为通知

json 示例:

{
    "type":"ClassA",
    "userId":10087
}

我转换它:

Notification notif = objectMapper.readValue(json, Notification.class);

它抛出异常:

java.lang.IllegalArgumentException: Can not construct instance of 
com.common.kafka.notification.NotificationPayload: abstract types
either need to be mapped to concrete types, have custom deserializer, or
contain additional type information
at [Source: N/A; line: -1, column: -1] (through reference chain:
com.common.kafka.notification.Notification["data"])

我读过这个问题:Cannot construct instance of - Jackson但似乎它没有帮助,因为我有太多的类从接口(interface)实现,而不仅仅是一次。

最佳答案

需要使用jackson的注解来实现多态反序列化。

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = ClassA.class, name = "ClassA"),
        @JsonSubTypes.Type(value = ClassB.class, name = "ClassB")
})
public interface NotificationPayload {
}

public class ClassA implements NotificationPayload {

    private Integer userId;

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }
}

public class Notification <T extends NotificationPayload> {

    private T data; //T may be ClassA/ClassB/ClassC.../ClassX

    @JsonCreator
    public Notification(T data) {
        this.data = data;
    }

    public static void main(String[] args) throws IOException {

        String jsonStr = "{\"type\":\"ClassB\",\"userId\":10087}";

        ObjectMapper objectMapper = new ObjectMapper();
        Notification notification = objectMapper.readValue(jsonStr, Notification.class);
    }
}

您可以找到的所有注释here

关于java - jackson 抛出 JsonMappingException 无法构造实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52181308/

相关文章:

java - 我想使用 XPath 检索 XML 属性值

javascript - Google map 更改复选框上的 JSON 叠加样式

树结构的 JSON 模式

java - com.fasterxml.jackson.core.JsonParseException : Unrecognized character escape 'U' (code 85)

java - 查询级别 2 缓存抛出 ClassCastException

java - session 超时后如何重定向到指定页面

java - 声明一个变量来存储字符串的第三个和第六个字符并测试它们是否是斜杠

mysql - 有没有办法将 JSON 字段中的数组与 MySQL 中的 JSON_ARRAY 进行比较?

java - 通用抽象类的自定义 Jackson 反序列化

java - 映射 JoinColum 值而不是 JSON 中的关联