本文介绍了杰克逊延迟反序列化字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一堂这样的课:

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 已经反序列化了……但是我可以通过 2 个步骤以某种方式完成此操作,也许使用 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 可能如下所示.对于 Product 类:

Example input JSON for those classes could look like this. For Product class:

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

Entity 类:

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

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

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

有用的链接:

  1. 如何转换 Java映射到/从 JSON (Jackson).
  2. java jackson 解析包含泛型类型对象的对象.

这篇关于杰克逊延迟反序列化字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!