使用spring boot将JSON反序列化为带有通用对象列表的POJO
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用spring boot将JSON反序列化为带有通用对象列表的POJO相关的知识,希望对你有一定的参考价值。
我正在尝试反序列化搜索API的JSON结果。搜索API(我在这里已简化)有一个主对象,其中包含有关搜索的元数据,然后列出搜索到的对象。我正在尝试使用通用对象列表来实现这一点
我没有测试过这些类,所有内容都完全符合我的要求。
test search.Java
public class TestSearch<T> {
private String count;
private List<T> results;
public String getCount() {
return count;
}
public void setCount(String count) {
this.count = count;
}
public List<T> getResults() {
return results;
}
public void setResults(List<T> results) {
this.results = results;
}
}
test result.Java
public class TestResult {
private String name;
private String description;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
test controller.Java
@RequestMapping("/test/json")
public String testGetJson() {
return "{"count":3,"results":[{"name":"result 1","description":"this is the first result","extra":"property"},{"name":"result 2","description":"tqbf"},{"name":"result 3","description":"jotlz"}]}";
}
@RequestMapping("/test/testserialize")
public List<TestResult> testSerialize() {
TestSearch<TestResult> testSearch = new RestTemplate().getForObject("http://localhost:8957/test/json", new TestSearch<TestResult>().getClass());
List<TestResult> results = testSearch.getResults();
results.forEach(result -> {
result.setName("new value");
});
return results;
}
JSON(只是为了让事情更具可读性)
{
"count": 3,
"results": [
{
"name": "result 1",
"description": "this is the first result",
"extra": "property"
},
{
"name": "result 2",
"description": "tqbf"
},
{
"name": "result 3",
"description": "jotlz"
}
]
}
在调用endpoint / test / testserialize后,我的应用程序抛出此错误
java.lang.ClassCastException:java.util.LinkedHashMap无法强制转换为com.testapp.entity.TestResult
现在,如果我返回并将TestSearch类更新为:
public class TestSearch {
private String count;
private List<TestResult> results;
public String getCount() {
return count;
}
public void setCount(String count) {
this.count = count;
}
public List<TestResult> getResults() {
return results;
}
public void setResults(List<TestResult> results) {
this.results = results;
}
}
我得到了我期待的结果:
[
{
"name": "new value",
"description": "this is the first result"
},
{
"name": "new value",
"description": "tqbf"
},
{
"name": "new value",
"description": "jotlz"
}
]
您需要为您使用的每个泛型类型创建一个TypeReference对象,并将其用于反序列化。例如,
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map = new HashMap<String, Object>();
// convert JSON string to Map
map = mapper.readValue(json, new TypeReference<Map<String, String>>(){});
在您的情况下,您将必须为其创建类型引用
public List<T> getResults()
如果您需要其他帮助,请告诉我。
getForObject函数内的getClass()方法看不到类型
要解决此问题,请使用ParameterizedTypeReference
TestSearch<TestResult> testSearch = new RestTemplate().exchange(
"http://localhost:8957/test/json",
HttpMethod.GET,
null,
new ParameterizedTypeReference<TestSearch<TestResult>>() {}).getBody();
我终于找到了一个恰好是6岁的解决方案:Generics with Spring RESTTemplate
以上是关于使用spring boot将JSON反序列化为带有通用对象列表的POJO的主要内容,如果未能解决你的问题,请参考以下文章
Spring-boot @RequestBody JSON 到带有日期反序列化示例的对象?
Spring Boot - 自定义 JSON 序列化 [重复]
如何将带有子属性的 JSON 反序列化为 C# 中的 ONE 对象