java/jersey 正在使用可能存在的列表解析 json 响应

java/jersey Parsing json response with possibly present list

我正在连接一个 api,它可以 return 对象或错误列表(抱歉,我将不得不提供虚构的示例,但它们应该是准确的):

预计json:

{
    "type":"someType",
    "list": [
        {
            "attribute":"someAttribute"
        }
    ]
}

错误时:

[
    {
        "error":"1",
        "someField":"someValue"
    }
]

使用 Jersey,我目前正在做这样的事情:

client.target(endpoint).request().post(Entity.json(request)).readEntity(ResponseObject.class);

ResponseObject.java

private List<Failure> messages;
private String type;
private List<ListObject> list;
// set/get

Failure.java

private String error;
private String someField;
// set/get

当我得到预期的 json 时,这似乎工作得很好,但是当 API return 出现错误时,我得到 JsonMappingException: Can not deserialize instance of [..] out of START_ARRAY token 异常。

当我收到错误时,我可以使用 response.readEntity(new GenericType<List<Failure>>(){});,但是我不知道在尝试解析响应之前它是否会失败。

有人知道如何解决这个问题吗?

因此,如果我可以执行以下操作,我的问题就会消失:

try {
    return response.readEntity(ResponseObject.class);
} catch (MappingException ex) {
    ResponseObject responseObject = new ResponseObject();
    responseObject.setFailureList(response.readEntity(new GenericType<List<Failure>>(){});
    return responseObject;
}

但是,readEntity 会关闭流,所以这是不可能的。

我最终做了一个解决方法,我首先从响应中读取字符串(以获取原始结果并关闭流),然后尝试解析它,如果我遇到初始解析错误,我会尝试将其解析为错误消息:

private <T> T parseAfterPayJson(String json, Class<T> responseClass) {
    Gson gson = new Gson();

    try {
        return gson.fromJson(json, responseClass);
    } catch (JsonSyntaxException jsex) {
        ResponseObject responseObject = new ResponseObject();
        responseObject.setFailures(Lists.newArrayList(gson.fromJson(json, Failure[].class)));
        return (T) responseObject; // this part is because of inheritance
    }
}