如何在 JAX-RS 中映射动态 JSON
How to map dynamic JSON in JAX-RS
我必须使用 JAX-RS(Resteasy 作为实现)将 JSON 映射到 Java PoJos。问题是 JSON 是动态的。看这个例子:
{
"typeCode": "SAMPLE",
"data": [
{
"id": "COMMENTS",
"answerValue": {
"type": "YesNoAnswer",
"value": true
}
},
{
"id": "CHOICE",
"answerValue": {
"type": "SelectListAnswer",
"values": ["choice1", "choice2"]
}
}
]
}
动态元素在数据数组中。原则上,每个条目都有一个 ID 和一个 answerValue。但是 answerValue 是动态的。根据他的类型,他可以有单个值(布尔值、字符串、数字对象)或值数组。
如何将其映射到我的 Java 模型?
我建议您通过将 answerValue
节点作为 JsonNode
类型来处理它,然后手动将其处理为您需要的 Java 类型。
大致如下:
class Data {
public String typeCode;
public List<Answer> data;
}
class Answer {
public String id;
public void setAnswerValue(JsonNode node) {
String type = node.path("type").asText();
switch (type) {
case "YesNoAnswer" :
boolean value = node.path("value").asBoolean();
// TODO Handle
break;
case "SelectListAnswer" :
JsonNode values = node.path("values");
for (JsonNode v : values) {
String s = v.textValue();
// TODO Handle
}
break;
}
}
}
然后可以使用 ObjectMapper
:
读取您的输入
ObjectMapper om = new ObjectMapper();
Data data = om.readValue(input, Data.class);
感谢@Henrik 的解决方案。在实施他的建议时,我找到了一个更适合我的不同解决方案。
我只是使用 JsonSubTypes Annotation 来处理继承。
这是我的例子:
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = YesNoAnswer.class, name = "YesNoAnswer"),
@JsonSubTypes.Type(value = SelectListAnswer.class, name="SelectListAnswer"),
@JsonSubTypes.Type(value = SelectAddressAnswer.class, name="SelectAddressAnswer")})
abstract class RequestFormAnswer {
private String type;
}
我必须使用 JAX-RS(Resteasy 作为实现)将 JSON 映射到 Java PoJos。问题是 JSON 是动态的。看这个例子:
{
"typeCode": "SAMPLE",
"data": [
{
"id": "COMMENTS",
"answerValue": {
"type": "YesNoAnswer",
"value": true
}
},
{
"id": "CHOICE",
"answerValue": {
"type": "SelectListAnswer",
"values": ["choice1", "choice2"]
}
}
]
}
动态元素在数据数组中。原则上,每个条目都有一个 ID 和一个 answerValue。但是 answerValue 是动态的。根据他的类型,他可以有单个值(布尔值、字符串、数字对象)或值数组。
如何将其映射到我的 Java 模型?
我建议您通过将 answerValue
节点作为 JsonNode
类型来处理它,然后手动将其处理为您需要的 Java 类型。
大致如下:
class Data {
public String typeCode;
public List<Answer> data;
}
class Answer {
public String id;
public void setAnswerValue(JsonNode node) {
String type = node.path("type").asText();
switch (type) {
case "YesNoAnswer" :
boolean value = node.path("value").asBoolean();
// TODO Handle
break;
case "SelectListAnswer" :
JsonNode values = node.path("values");
for (JsonNode v : values) {
String s = v.textValue();
// TODO Handle
}
break;
}
}
}
然后可以使用 ObjectMapper
:
ObjectMapper om = new ObjectMapper();
Data data = om.readValue(input, Data.class);
感谢@Henrik 的解决方案。在实施他的建议时,我找到了一个更适合我的不同解决方案。 我只是使用 JsonSubTypes Annotation 来处理继承。 这是我的例子:
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = YesNoAnswer.class, name = "YesNoAnswer"),
@JsonSubTypes.Type(value = SelectListAnswer.class, name="SelectListAnswer"),
@JsonSubTypes.Type(value = SelectAddressAnswer.class, name="SelectAddressAnswer")})
abstract class RequestFormAnswer {
private String type;
}