问题描述
我有这样的课程:
public class DeserializedHeader
int typeToClassId;
Object obj
我知道什么类型的对象obj基于typeToClassId,这是遗憾的是只在运行时才知道。
I know what type of object obj is based on the typeToClassId, which is unfortunately only known at runtime.
我想根据typeToClassId解析obj - 这里最好的方法是什么?注释似乎已经出局了,基于ObjectMapper的东西似乎是正确的,但我很难弄清楚最好的方法可能是什么。
I want to parse obj out based on typeToClassId - what's the best approach here? Annotations seem like they're out, and something based on ObjectMapper seems right, but I'm having trouble figuring out what the best approach is likely to be.
类clazz = lookUpClassBasedOnId(typeToClassId)
objectMapper.readValue(obj,clazz)
Something along the lines of Class clazz = lookUpClassBasedOnId(typeToClassId) objectMapper.readValue(obj, clazz)
显然,这不起作用,因为obj已经被反序列化...但是我可以用两个步骤以某种方式执行此操作,也许使用convertValue?
Obviously, this doesn't work since obj is already deserialized... but could I do this in 2 steps somehow, perhaps with convertValue?
推荐答案
这真的很复杂,痛苦的问题。我不知道任何复杂而优雅的解决方案,但我可以与您分享我开发的想法。我创建了示例程序,帮助我向您展示如何解决您的问题。一开始我创建了两个简单的POJO类:
This is really complex and painful problem. I do not know any sophisticated and elegant solution, but I can share with you my idea which I developed. I have created example program which help me to show you how you can solve your problem. At the beginning I have created two simple POJO classes:
class Product {
private String name;
// getters/setters/toString
}
和
class Entity {
private long id;
// getters/setters/toString
}
示例这些类的输入JSON可能如下所示。对于产品
类:
Example input JSON for those classes could look like this. For Product
class:
{
"typeToClassId" : 33,
"obj" : {
"name" : "Computer"
}
}
和实体
类:
{
"typeToClassId" : 45,
"obj" : {
"id" : 10
}
}
我们想要使用的主要功能是部分序列化/反序列化。为此,我们将启用功能。现在我们必须创建两个定义 typeToClassId
和 obj
属性的类。
The main functionality which we want to use is "partial serializing/deserializing". To do this we will enable FAIL_ON_UNKNOWN_PROPERTIES
feature on ObjectMapper
. Now we have to create two classes which define typeToClassId
and obj
properties.
class HeaderType {
private int typeToClassId;
public int getTypeToClassId() {
return typeToClassId;
}
public void setTypeToClassId(int typeToClassId) {
this.typeToClassId = typeToClassId;
}
@Override
public String toString() {
return "HeaderType [typeToClassId=" + typeToClassId + "]";
}
}
class HeaderObject<T> {
private T obj;
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
@Override
public String toString() {
return "HeaderObject [obj=" + obj + "]";
}
}
最后,源代码可以解析JSON:
And, finally source code which can parse JSON:
// Simple binding
Map<Integer, Class<?>> classResolverMap = new HashMap<Integer, Class<?>>();
classResolverMap.put(33, Product.class);
classResolverMap.put(45, Entity.class);
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
String json = "{...}";
// Parse type
HeaderType headerType = mapper.readValue(json, HeaderType.class);
// Retrieve class by integer value
Class<?> clazz = classResolverMap.get(headerType.getTypeToClassId());
// Create dynamic type
JavaType type = mapper.getTypeFactory().constructParametricType(HeaderObject.class, clazz);
// Parse object
HeaderObject<?> headerObject = (HeaderObject<?>) mapper.readValue(json, type);
// Get the object
Object result = headerObject.getObj();
System.out.println(result);
有用的链接:
- 。
- 。
- How To Convert Java Map To / From JSON (Jackson).
- java jackson parse object containing a generic type object.
这篇关于杰克逊推迟反序列化领域的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!