如何使用 Sprint Rest 模板解析 json 与混合子对象
How to parse json with mixed child objects using Sprint Rest Template
我有一个 json 回复,如下所示
{
"resourceType": "Topic",
"metadata": {
"lastUpdated": "2016-12-15T14:51:33.490-06:00"
},
"entry": [
{
"resource": {
"resourceType": "Outcome",
"issue": [
{
"response": "error",
"code": "exception"
},
{
"response": "success",
"code": "informational"
},
{
"response": "success",
"code": "informational"
}
]
}
},
{
"resource": {
"resourceType": "Data",
"id": "80",
"subject": {
"reference": "dataFor/80"
},
"created": "2016-06-23T04:29:00",
"status": "current"
}
},
{
"resource": {
"resourceType": "Data",
"id": "90",
"subject": {
"reference": "dataFor/90"
},
"created": "2016-06-23T04:29:00",
"status": "current"
}
}
]
}
数据和结果Class 扩展资源。
我正在使用 Spring RestTemplate.getForObject(url, someClass)。我遇到以下错误
has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Could not read JSON: Unrecognized field "response" (Class com.model.Resource), not marked as ignorable
at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@77a3e67a;
我知道 json 没有被解析为资源的子 class。我想做类似 RestTemplate.getForObject(url, someClass) 的事情,但这不受 java 泛型(通配符)支持。请帮忙
您需要使用 jackson 反序列化为动态类型,使用 resourceType 作为字段来指示实际类型。将这些添加到您的资源 class.
@JsonTypeInfo(property = "resourceType", use = Id.NAME)
@JsonSubTypes({ @Type(Data.class),
@Type(Outcome.class)
})
这是一个单元测试,可以证明该行为。
@Test
public void deserializeJsonFromResourceIntoData () throws IOException {
Data data = (Data) new ObjectMapper().readValue("{" +
" \"resourceType\": \"Data\"," +
" \"id\": \"80\"," +
" \"subject\": {" +
" \"reference\": \"dataFor/80\"" +
" }," +
" \"created\": \"2016-06-23T04:29:00\"," +
" \"status\": \"current\"" +
" }", Resource.class);
assertEquals(Integer.valueOf(80), data.getId());
assertEquals("dataFor/80", data.getSubject().getReference());
}
至于转换,我在这里只是为了证明它的工作原理,然而,要真正多态,你可能希望让 Resource 包含你需要的所有行为,然后一切都只是一个 Resource .
我有一个 json 回复,如下所示
{
"resourceType": "Topic",
"metadata": {
"lastUpdated": "2016-12-15T14:51:33.490-06:00"
},
"entry": [
{
"resource": {
"resourceType": "Outcome",
"issue": [
{
"response": "error",
"code": "exception"
},
{
"response": "success",
"code": "informational"
},
{
"response": "success",
"code": "informational"
}
]
}
},
{
"resource": {
"resourceType": "Data",
"id": "80",
"subject": {
"reference": "dataFor/80"
},
"created": "2016-06-23T04:29:00",
"status": "current"
}
},
{
"resource": {
"resourceType": "Data",
"id": "90",
"subject": {
"reference": "dataFor/90"
},
"created": "2016-06-23T04:29:00",
"status": "current"
}
}
]
}
数据和结果Class 扩展资源。
我正在使用 Spring RestTemplate.getForObject(url, someClass)。我遇到以下错误
has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Could not read JSON: Unrecognized field "response" (Class com.model.Resource), not marked as ignorable
at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@77a3e67a;
我知道 json 没有被解析为资源的子 class。我想做类似 RestTemplate.getForObject(url, someClass) 的事情,但这不受 java 泛型(通配符)支持。请帮忙
您需要使用 jackson 反序列化为动态类型,使用 resourceType 作为字段来指示实际类型。将这些添加到您的资源 class.
@JsonTypeInfo(property = "resourceType", use = Id.NAME)
@JsonSubTypes({ @Type(Data.class),
@Type(Outcome.class)
})
这是一个单元测试,可以证明该行为。
@Test
public void deserializeJsonFromResourceIntoData () throws IOException {
Data data = (Data) new ObjectMapper().readValue("{" +
" \"resourceType\": \"Data\"," +
" \"id\": \"80\"," +
" \"subject\": {" +
" \"reference\": \"dataFor/80\"" +
" }," +
" \"created\": \"2016-06-23T04:29:00\"," +
" \"status\": \"current\"" +
" }", Resource.class);
assertEquals(Integer.valueOf(80), data.getId());
assertEquals("dataFor/80", data.getSubject().getReference());
}
至于转换,我在这里只是为了证明它的工作原理,然而,要真正多态,你可能希望让 Resource 包含你需要的所有行为,然后一切都只是一个 Resource .