如何使用通用对象列表将 JSON 反序列化为复杂的 POJO<>
How to deserialize JSON to complex POJO<> with List of Generic Objects
我用jackson-databind 2.8.0
我反对通用数据
public class JsonItem<T> implements Serializable {
private static final long serialVersionUID = -8435937749132073097L;
@JsonProperty(required = true)
private boolean success;
@JsonProperty(required = false)
private T data;
@JsonProperty(required = false)
private Map<String, String> errors = new HashMap<>();
JsonItem() {
}
public boolean getSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public Map<String, String> getErrors() {
return errors;
}
public void setErrors(Map<String, String> errors) {
this.errors = errors;
}
}
并且有对象
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class DepositInfoDto implements Serializable {
private static final long serialVersionUID = -4123441934244992311L;
@NotNull
@JsonProperty(required = true)
private String productName;
@NotNull
@JsonProperty(required = true)
private String contractName;
@NotNull
@JsonProperty(required = true)
private List<ContractDto> contracts;
@NotNull
@JsonProperty(required = true)
private StatusDto status;
//...getters and setters
}
我收到了类似 JsonItem<List<DepositInfoDto>>
的对象。
我尝试创建通用方法来取消现实化
public <T> List<T> getObjects(){
ObjectMapper mapper = new ObjectMapper();
List<T> myObjects = mapper.readValue(jsonInput, new TypeReference<JsonItem<List<T>>(){});
return myObjects;
}
无效,因为 T 在运行时转换为 Object
public List<DepositInfoDto> getObjects(){
ObjectMapper mapper = new ObjectMapper();
List<DepositInfoDto> myObjects = mapper.readValue(jsonInput, new TypeReference<JsonItem<List<DepositInfoDto >>(){});
return myObjects;
}
有效,但我想要通用方法,因为我有 DepositInfoDto, CardinfoDto, ContractDto
等
我看到方法了
public List<T> getObjects(Class<T> clazz){
ObjectMapper mapper = new ObjectMapper();
List<T> myObjects = mapper.readValue(jsonInput, mapper.getTypeFactory().constructCollectionType(List.class, clazz));
return myObjects;
}
但没有用,因为我有 JsonItem
数据 List<T>
我该如何解决这个问题?也许 mapper.getTypeFactory()
有像 mapper.getTypeFactory().constructType(JsonItem.class, List.class,DepositInfoDto.class)
这样复杂的方法
编辑
以我为例
ObjectMapper mapper = new ObjectMapper();
try {
JsonItem<T> item = mapper.readValue(objectWrapper.get(0), mapper.getTypeFactory().constructParametricType(
JsonItem.class, mapper.getTypeFactory().constructCollectionType(List.class, resourceClass)));
return item.getData();
} catch (IOException e) {
LOG.error("Can't deserialize JSON to class: "+ resourceClass +". Error: " + e);
Thread.currentThread().interrupt();
}
您可以使用 TypeFactory#constructParametricType
为 JsonItem<T>
创建 JavaType
,然后使用 TypeFactory#constructCollectionType
为 List<JsonItem<T>>
创建 CollectionType
。以下是示例:
public <T> List<JsonItem<T>> getObjects(String jsonInput, Class<T> clazz) {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(jsonInput, mapper.getTypeFactory().constructCollectionType(
List.class, mapper.getTypeFactory().constructParametricType(JsonItem.class, clazz)));
}
我用jackson-databind 2.8.0
我反对通用数据
public class JsonItem<T> implements Serializable {
private static final long serialVersionUID = -8435937749132073097L;
@JsonProperty(required = true)
private boolean success;
@JsonProperty(required = false)
private T data;
@JsonProperty(required = false)
private Map<String, String> errors = new HashMap<>();
JsonItem() {
}
public boolean getSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public Map<String, String> getErrors() {
return errors;
}
public void setErrors(Map<String, String> errors) {
this.errors = errors;
}
}
并且有对象
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class DepositInfoDto implements Serializable {
private static final long serialVersionUID = -4123441934244992311L;
@NotNull
@JsonProperty(required = true)
private String productName;
@NotNull
@JsonProperty(required = true)
private String contractName;
@NotNull
@JsonProperty(required = true)
private List<ContractDto> contracts;
@NotNull
@JsonProperty(required = true)
private StatusDto status;
//...getters and setters
}
我收到了类似 JsonItem<List<DepositInfoDto>>
的对象。
我尝试创建通用方法来取消现实化
public <T> List<T> getObjects(){
ObjectMapper mapper = new ObjectMapper();
List<T> myObjects = mapper.readValue(jsonInput, new TypeReference<JsonItem<List<T>>(){});
return myObjects;
}
无效,因为 T 在运行时转换为 Object
public List<DepositInfoDto> getObjects(){
ObjectMapper mapper = new ObjectMapper();
List<DepositInfoDto> myObjects = mapper.readValue(jsonInput, new TypeReference<JsonItem<List<DepositInfoDto >>(){});
return myObjects;
}
有效,但我想要通用方法,因为我有 DepositInfoDto, CardinfoDto, ContractDto
等
我看到方法了
public List<T> getObjects(Class<T> clazz){
ObjectMapper mapper = new ObjectMapper();
List<T> myObjects = mapper.readValue(jsonInput, mapper.getTypeFactory().constructCollectionType(List.class, clazz));
return myObjects;
}
但没有用,因为我有 JsonItem
数据 List<T>
我该如何解决这个问题?也许 mapper.getTypeFactory()
有像 mapper.getTypeFactory().constructType(JsonItem.class, List.class,DepositInfoDto.class)
编辑
以我为例
ObjectMapper mapper = new ObjectMapper();
try {
JsonItem<T> item = mapper.readValue(objectWrapper.get(0), mapper.getTypeFactory().constructParametricType(
JsonItem.class, mapper.getTypeFactory().constructCollectionType(List.class, resourceClass)));
return item.getData();
} catch (IOException e) {
LOG.error("Can't deserialize JSON to class: "+ resourceClass +". Error: " + e);
Thread.currentThread().interrupt();
}
您可以使用 TypeFactory#constructParametricType
为 JsonItem<T>
创建 JavaType
,然后使用 TypeFactory#constructCollectionType
为 List<JsonItem<T>>
创建 CollectionType
。以下是示例:
public <T> List<JsonItem<T>> getObjects(String jsonInput, Class<T> clazz) {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(jsonInput, mapper.getTypeFactory().constructCollectionType(
List.class, mapper.getTypeFactory().constructParametricType(JsonItem.class, clazz)));
}