假设我有一个模型课程fo:region-body
Document document = new Document();
我想做的是将通用类型传递给类ResponseModel
,当我调用方法@Setter // This one not working
public class ResponseModel<T> {
private Class<T> responseClass;
private String content; // JsonString
public <T> T getContent() throws IOException {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(content, responseClass);
}
}
时,它应该根据responseClass返回映射的对象
这是我想做的一个例子
ResponseModel
有人知道该怎么做吗?
答案 0 :(得分:1)
您可以使用静态方法反序列化具有通用类型的对象
public class MyDeserializer {
private static final ObjectMapper objectMapper = new ObjectMapper();
public static <T> T convertValue(String content, Class<T> contentClass) throws IOException {
Assert.notNull(content, "Content cannot be null");
Assert.notNull(contentClass, "Content class must be specified");
return objectMapper.readValue(content, contentClass);
}
}
并测试您的方法:
Color color = MyDeserializer.convertValue("{" +
"\"nameValue\":\"red\"," +
"\"hexValue\":\"FFFFFF\"" + "}", Color.class);
assertEquals("red", color.getNameValue());
assertEquals("FFFFFF", color.getHexValue());
通过这种方式,您可以在运行时将反序列化器用于任何类。
更新
要使示例工作正常,您需要在getContent之前将其删除以与类中的通用类型T匹配。
public T getContent() throws IOException {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(content, responseClass);
}
并使用您的方法:
responseModel.setContent("{" +
"\"nameValue\":\"red\"," +
"\"hexValue\":\"FFFFFF\"" + "}");
responseModel.setResponseClass(Color.class);
在运行时,通用类型被Object取代,因此必须指定所需的类。
我仍然认为第一个解决方案是干净的解决方案。您在询问是否可以推断出T类,但在运行时看不到T的类型。
答案 1 :(得分:0)
您可以使用JsonSubTypes
编写一个接口,以自动进行反序列化,如下所示:
@JsonIgnoreProperties(value = {"type"})
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Subclass1.class, name = "SUBCLASS1"),
@JsonSubTypes.Type(value = Subclass2.class, name = "SUBCLASS2")
})
public interface DeserializableModelInterface {
}
并使用此特定对象写您的ResponseModel
public class ResponseModel<T extends AbstractDeserializer> {
private T body;
public ResponseModel(T body) {
this.body = body;
}
public T getBody() {
return body;
}
}
您的body
是一个特定的对象,您可以在运行时获取它而无需显式转换json
在您的Subclass1
,Subclass2
等中,您将拥有一个附加的json属性,该属性将允许jackson自动进行反序列化/序列化
{
"type": "SUBCLASS1"
... other properties
}
要避免手动映射子类值,可以使用类名,例如:
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "class")