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

时间:2018-12-14 11:59:57

标签: java json jackson deserialization jackson2

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

成功json示例。

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

示例失败json

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

我目前正在使用的Java类可以对成功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数组包含在构造函数中,则我没有名称/值来引用项目数组,并且代码会引发异常。

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

我该如何实现? 或者,我还能如何构造我的代码以处理多种预期的json格式? 我知道我可以反序列化为TreeMap,检查格式,然后再次转换为最终对象,例如,但是我想跳过此中间步骤。

感谢任何人都可以给我的建议:)

2 个答案:

答案 0 :(得分:2)

您可以尝试创建超类

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 {...}

与相应的构造函数。这些属性将位于超类中。 使用这些类时,应将它们称为ResponseObject类。

答案 1 :(得分:0)

如果为错误消息添加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;
    }

}