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;
}
}
我正在从 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;
}
}