2

我有这样的课:

public class DeserializedHeader
    int typeToClassId;
    Object obj

我知道基于 typeToClassId 的对象 obj 的类型,不幸的是,它仅在运行时才知道。

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

类似于 Class clazz = lookUpClassBasedOnId(typeToClassId) objectMapper.readValue(obj, clazz) 的东西

显然,这是行不通的,因为 obj 已经反序列化了……但是我可以通过 2 步以某种方式执行此操作,也许使用 convertValue 吗?

4

1 回答 1

3

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

class Product {

    private String name;

        // getters/setters/toString
}

class Entity {

    private long id;

    // getters/setters/toString
}

这些类的示例输入 JSON 可能如下所示。对于Product班级:

{
  "typeToClassId" : 33,
  "obj" : {
    "name" : "Computer"
  }
}

Entity上课:

{
  "typeToClassId" : 45,
  "obj" : {
    "id" : 10
  }
}

我们要使用的主要功能是“部分序列化/反序列化”。为此,我们将FAIL_ON_UNKNOWN_PROPERTIES启用ObjectMapper. 现在我们必须创建两个定义typeToClassIdobj属性的类。

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 的源代码:

// 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);

有用的网址:

  1. 如何将 Java 地图转换为 JSON(杰克逊)
  2. java jackson 解析包含泛型类型对象的对象
于 2013-07-13T00:04:35.977 回答