Java jackson延迟反序列化字段

Java jackson延迟反序列化字段,java,jackson,Java,Jackson,我有一门课是这样的: public class DeserializedHeader int typeToClassId; Object obj 我知道什么类型的对象obj是基于typeToClassId的,不幸的是只有在运行时才知道 我想基于typeToClassId解析obj——这里最好的方法是什么?注释似乎已经过时了,基于ObjectMapper的东西似乎是正确的,但我很难弄清楚最好的方法可能是什么 类似于 clazz类=lookUpClassBasedOnId(type

我有一门课是这样的:

public class DeserializedHeader
    int typeToClassId;
    Object obj
我知道什么类型的对象obj是基于typeToClassId的,不幸的是只有在运行时才知道

我想基于typeToClassId解析obj——这里最好的方法是什么?注释似乎已经过时了,基于ObjectMapper的东西似乎是正确的,但我很难弄清楚最好的方法可能是什么

类似于 clazz类=lookUpClassBasedOnId(typeToClassId) objectMapper.readValue(obj,clazz)


显然,这不起作用,因为obj已经反序列化了。。。但我可以用convertValue分两步完成吗?

这确实是一个复杂而痛苦的问题。我不知道任何复杂和优雅的解决方案,但我可以与您分享我的想法,我开发。我创建了一个示例程序,帮助我向您展示如何解决您的问题。开始时,我创建了两个简单的POJO类:

class Product {

    private String name;

        // getters/setters/toString
}

这些类的示例输入JSON如下所示。对于
产品
类别:

{
  "typeToClassId" : 33,
  "obj" : {
    "name" : "Computer"
  }
}
{
  "typeToClassId" : 45,
  "obj" : {
    "id" : 10
  }
}
对于
实体
类:

{
  "typeToClassId" : 33,
  "obj" : {
    "name" : "Computer"
  }
}
{
  "typeToClassId" : 45,
  "obj" : {
    "id" : 10
  }
}
我们要使用的主要功能是“部分序列化/反序列化”。为此,我们将启用
ObjectMapper
上的功能。现在我们必须创建两个类来定义
typeToClassId
obj
属性

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 + "]";
    }
}
班长类型{
私有int-typeToClassId;
public int getTypeToClassId(){
返回typeToClassId;
}
公共无效setTypeToClassId(int-typeToClassId){
this.typeToClassId=typeToClassId;
}
@凌驾
公共字符串toString(){
返回“HeaderType[typeToClassId=“+typeToClassId+”””;
}
}
类标题对象{
私人T obj;
公共T getObj(){
返回obj;
}
公共无效设置对象(T对象){
this.obj=obj;
}
@凌驾
公共字符串toString(){
返回“HeaderObject[obj=“+obj+”]”;
}
}
最后是可以解析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);
//简单绑定
地图>();
classResolverMap.put(33,产品类);
classResolverMap.put(45,Entity.class);
ObjectMapper mapper=新的ObjectMapper();
禁用(反序列化功能。在未知属性上失败);
字符串json=“{…}”;
//解析类型
HeaderType HeaderType=mapper.readValue(json,HeaderType.class);
//按整数值检索类
Class clazz=classResolverMap.get(headerType.getTypeToClassId());
//创建动态类型
JavaType type=mapper.getTypeFactory().ConstructParameterType(HeaderObject.class,clazz);
//解析对象
HeaderObject HeaderObject=(HeaderObject)mapper.readValue(json,类型);
//获取对象
对象结果=headerObject.getObj();
系统输出打印项次(结果);
有用链接:


  • 这是个很臭的设计。为什么类型为
    对象
    ?为什么只有在运行时才知道它?你能创建一个映射吗?你肯定同意代码的味道-但是,它是第三方服务,所以我不能真正控制它基本上,在解析typeToClassId字段之后,我将知道obj字段中的对象类型。