Java Jackson 将纯 Json 数组或 Json 对象反序列化为单个 Java 对象 (POJO)

Java Jackson Deserialize Plain Json Array or Json Object into a Single Java Object (POJO)

我正在从 API 端点检索数据,该端点 returns 数据采用两种不同的预期 json 格式。响应之一是成功响应,响应之一是失败响应。 API 中的其他端点类似,也有成功和失败格式。对于大多数端点,我只是将两种类型的响应反序列化为单个 Java 对象,其中某些字段在不存在时仅设置为 default/null 值。 这个端点的问题是成功响应是一个 json 数组,失败响应是一个 json 对象。我已经尝试了一切以找到一种将这两种可能的响应反序列化为单个 java 对象的简单方法。

成功示例 json。

[
    {
        "item1": "somevalue1",
        "item2": "somevalue2"
    },
    {
        "item1": "somevalue3",
        "item2": "somevalue4"
    },
    ..
    ..
]

示例失败json

{
    "success": false,
    "errorMessage": "something went wrong "
}

我的 Java class 我目前正在使用 works 反序列化成功 json 但不反序列化失败 json.

public class ResponseObject {
    public final boolean success;
    public final String errorMessage;
    public final List<MyItem> items;

    @JsonCreator
    public ResponseObject(ArrayList<MyItem> items) {
       this.items = items;
    }

}

而且我还有一个适用于失败案例但不适用于成功案例的构造函数

public class ResponseObject {
    public final boolean success;
    public final String errorMessage;
    public final List<MyItem> items;

    @JsonCreator
    public ResponseObject(@JsonProperty("success") Boolean success, @JsonProperty("errorMessage") String errorMessage){
        this.success = success == null;
        this.errorMessage = errorMessage;
        this.items = items;
    }

}

我的反序列化代码看起来像

ObjectReader objectReader = objectMapper.readerFor(ResponseObject.class);
Object json = objectReader.readValue(inputStream);

无论我试图反序列化这两种情况的任何策略似乎都失败了。如果我尝试使用 @JsonProperty 在构造函数中包含 json 数组,那么我没有 name/value 来引用项目数组,并且代码会引发异常。

我需要的是一种将两个响应反序列化为我概述的 ResponseObject 格式的方法,当我获得成功响应时,成功字段应该为真,errorMessage 应该为 null,并且项目应该包含 MyItem 列表. 当我收到失败响应时,成功应该为假,errorMessage 应该有一个字符串消息,项目列表应该为空。

我怎样才能做到这一点? 或者,我还能如何构建我的代码来处理多种预期的 json 格式? 我知道我可以反序列化为 TreeMap,检查格式,然后再次转换为最终对象,但我想跳过这个中间步骤。

感谢任何人在这方面给我的任何建议:)

你可以尝试做一个超级class

public class ResponseObject {

    public final boolean success;
    public final String errorMessage;
    public final List<MyItem> items;

    ...
}

然后在

中组织失败和成功消息
public class SuccesResponseObject extends ResponseObject {...}

public class FailResponseObject extends ResponseObject {...}

与相应的构造函数。这些属性将位于 superclass 中。 使用 classes 时,您应该参考 class ResponseObject.

中的它们

如果您为错误消息添加一个 POJO,您可以将第二个 JsonCreator 添加到您的响应对象。

public class ErrorResponse {
    private boolean success;
    private String errorMessage;
    public boolean isSuccess() {
        return success;
    }
    public void setSuccess(boolean success) {
        this.success = success;
    }
    public String getErrorMessage() {
        return errorMessage;
    }
    public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }
}

使用 2 个 JsonCreator 修改 ResponseObject

public class ResponseObject {
    public final boolean success;
    public final String errorMessage;
    public final List<MyItem> items;

    @JsonCreator
    public ResponseObject(List<MyItem> items) {
       this.success = true;
       this.errorMessage = null;
       this.items = items;
    }

    @JsonCreator
    public ResponseObject(ErrorResponse error){
        this.success = error.isSuccess();
        this.errorMessage = error.getErrorMessage();
        this.items = null;
    }

}