当前位置: 首页 > 知识库问答 >
问题:

jackson延迟反序列化字段

弘伟彦
2023-03-14

我有这样一门课:

public class DeserializedHeader
    int typeToClassId;
    Object obj

我知道基于typeToClassId的对象obj是什么类型,不幸的是只有在运行时才知道。

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

类似于类clazz=lookUpClassBasedOnId(typeToClassId)objectMapper的内容。readValue(对象、类别)

显然,这不起作用,因为obj已经反序列化了...但是我能以某种方式在2个步骤中做到这一点吗,也许可以使用转换值?

共有1个答案

童铭晨
2023-03-14

这真是一个复杂而痛苦的问题。我不知道有什么复杂而优雅的解决方案,但我可以和你们分享我的想法。我创建了一个示例程序,帮助我向您展示如何解决您的问题。起初,我创建了两个简单的POJO类:

class Product {

    private String name;

        // getters/setters/toString
}

class Entity {

    private long id;

    // getters/setters/toString
}

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

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

对于实体类:

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

我们要使用的主要功能是“部分序列化/反序列化”。为此,我们将在对象映射器上启用未知属性上的失败功能。现在,我们必须创建两个类来定义类型toclassid和对象属性。

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(Jackson)或从JSON(Jackson)转换为Java映射
 类似资料:
  • 问题内容: 我有这样的课: 我知道哪种类型的对象obj基于typeToClassId,不幸的是仅在运行时才知道。 我想根据typeToClassId解析obj- 最好的方法是什么?注解似乎已经消失了,基于ObjectMapper的东西似乎是正确的,但是我在弄清楚最好的方法是什么时遇到了麻烦。 类clazz = lookUpClassBasedOnId(typeToClassId)objectMap

  • 我使用Spring并创建了一个REST服务。 这是我的控制器的一部分: 该人员的角色是延迟初始化的,当时不需要。当(1)被注释掉时,所有操作都将失败 org.springframework.http.converter.HttpMessageNotWritableException:无法写入JSON:无法延迟初始化角色集合:no.something.project.Person.roles,无法初

  • 我有以下xml 我需要将其反序列化为以下POJO: 这里的问题是被包装在元素中

  • 我在试着读我的。json文件。Is是一个车辆存储类。 这是错误: com.fasterxml.jackson.databind.exc.MismatchedInputException:无法构造的实例(尽管至少存在一个Creator):无法构造的实例(尽管至少存在一个Creator):没有字符串参数构造函数/工厂方法来从[Source:(File); line: 1,列: 1]处的字符串值反序列化

  • 问题内容: 我无法找出使用杰克逊实现自定义序列化/反序列化的正确方法。我有很多类(〜50),它们带有应被序列化/反序列化而不是原始的原始字段。喜欢: 所有序列化和反序列化都非常相似,我只需要在整数之后添加一个后缀(C,页面,米等)。 一种简单的方法是在每个这样的字段中添加一对/ 注释并实现它们。但是我最终会得到100个 非常相似的 序列化器/反序列化器。 我想到了添加自定义注释的各个领域,说或,这

  • 可以序列化/反序列化< code >映射吗 在这种特殊情况下,我知道总是,和 - 第三方类(我有序列化器和反序列化器),其他值是盒装原语。 有可能和杰克逊做这样的事吗?使用MapSerializer/MapDeserializer可以做到这一点吗?(我找不到任何例子)