我有class Response
,其属性为data
。
json文件映射到此对象。 data
属性可以是json上的TaskData
或SubmitData
类型。
如果json具有类型为TaskData
的对象,则对象映射器必须映射到TaskData
类,或者应映射到“SubmitData”类。
答案 0 :(得分:1)
除了Guillaume Polet的回答,如果你可以修改JSON模式,使用Jackson的Polymorphic (de)serialization通过注释也可以更顺畅地完成:
@JsonTypeInfo(use=JsonTypeInfo.Id.Class, include=JsonTypeInfo.As.PROPERTY, property="@class")
class Data {}
class TaskData extends Data {}
class SubmitData extends Data {}
这将写出完整的Java类名作为额外的@class
属性。但是,json需要在输入中包含@class
属性。
代替JsonTypeInfo.Id.Class
,也可以执行显式命名
@JsonTypeInfo(use=JsonTypeInfo.Id.Class, include=JsonTypeInfo.As.PROPERTY, property="@dataType")
@JsonSubTypes({
JsonSubTypes.Type(value=TaskData.class, name="task"),
JsonSubTypes.Type(value=SubmitData.class, name="submit")
})
class Data {}
@JsonTypeName("task")
class TaskData extends Data {}
@JsonTypeName("submit")
class SubmitData extends Data {}
这将产生一个额外的合成字段@dataType
,它将需要出现在输入中。
如果您无法在输入JSON中明确显示类型,则需要坚持手动方法。
答案 1 :(得分:0)
您需要按以下方式输入Response
课程:public class Response<T>
。
然后,在反序列化输入时,向jackson提供TypeReference
以指示所需的类型。
见这个例子:
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class TestJacksonTyping {
public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
Response<TaskData> taskResponse = new Response<TaskData>();
TaskData taskData = new TaskData();
taskData.setTaskTitle("Some title");
taskResponse.setData(taskData);
Response<SubmitData> submitResponse = new Response<SubmitData>();
SubmitData submitData = new SubmitData();
submitData.setSubmitValue(256);
submitResponse.setData(submitData);
StringWriter sw = new StringWriter();
mapper.writeValue(sw, taskResponse);
String taskResponseJson = sw.toString();
mapper.writeValue(sw = new StringWriter(), submitResponse);
String submitResponseJson = sw.toString();
Response<TaskData> deserializedTaskResponse = mapper.reader(new TypeReference<Response<TaskData>>() {
}).readValue(new StringReader(taskResponseJson));
Response<SubmitData> deserializedSubmitResponse = mapper.reader(new TypeReference<Response<SubmitData>>() {
}).readValue(new StringReader(submitResponseJson));
System.out.println(deserializedTaskResponse.getData().getTaskTitle());
System.out.println(deserializedSubmitResponse.getData().getSubmitValue());
}
public static class Response<T> {
private T data;
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
public static class TaskData {
private String taskTitle;
public String getTaskTitle() {
return taskTitle;
}
public void setTaskTitle(String taskTitle) {
this.taskTitle = taskTitle;
}
}
public static class SubmitData {
private int submitValue;
public int getSubmitValue() {
return submitValue;
}
public void setSubmitValue(int submitValue) {
this.submitValue = submitValue;
}
}
}