简体   繁体   English

用杰克逊解析JSON到深度嵌套的泛型

[英]Parse JSON to deeply nested generic with jackson

I've been trying all kinds of solutions to get this working. 我一直在尝试各种解决方案以使其正常工作。 But without success. 但是没有成功。

I have a few classes like this 我有几个这样的课程

class Level1<T> {

    public Level2<T> l2;
}

class Level2<T> {

    public Level3<T> l3;
}

class Level3<T> {

    public List<T> objectsList;
}

T in this case can be any object , and should be possible to be resolved during runtime . 在这种情况下, T 可以是任何对象 ,并且应该可以在运行时解析

My JSON looks like this: 我的JSON看起来像这样:

{
    "Level1": {
        "Level2": {
            "Level3": {
                "genericObject": [
                    { 
                      "attribute1": ..., 
                      "attribute2": ...
                    },
                    { 
                      "attribute1": ..., 
                      "attribute2": ...
                    } 
                ]
            }
        }
    }
}

The JSON property "genericObject" changes its name and attributes depending of which kind of object I'm receiving. JSON属性“ genericObject”根据我要接收的对象类型更改其名称和属性。

I've tried defining in my ObjectMapper like this, in which I pass a Class object to my function (genericObjectClass): 我尝试像这样在ObjectMapper中进行定义,在其中将Class对象传递给函数(genericObjectClass):

JavaType javaType = TypeFactory.defaultInstance().constructParametricType(ArrayList.class, List.class, genericObjectClass);
javaType = TypeFactory.defaultInstance().constructParametricType(Level3.class, javaType);
javaType = TypeFactory.defaultInstance().constructParametricType(Level2.class, javaType);
javaType = TypeFactory.defaultInstance().constructParametricType(Level1.class, javaType);

Level1<genericObject> l1 = objectMapper.readValue(jsonString, javaType);

Tried solutions: 尝试过的解决方案:

(de)serialising Nested Generics in Jackson 杰克逊的(反)序列化嵌套泛型

How to use Jackson with Generics 如何在泛型中使用Jackson

Is Jackson really unable to deserialize json into a generic type? Jackson真的无法将json反序列化为通用类型吗?

There are several things that you need to change 您需要更改几件事

  1. Level1 object is not the root object, but a field. Level1对象不是根对象,而是一个字段。 If you don't want to create one more wrapper object, use UNWRAP_ROOT_VALUE 如果您不想再创建一个包装对象,请使用UNWRAP_ROOT_VALUE

     mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE); 
  2. You don't need to constructParametricType for the whole object hierarchy, just construct it for top class in the chain 你并不需要constructParametricType整个对象层次结构,只是构建它顶级链

     constructParametricType(Level1.class, genericObjectClass); 
  3. Your json fields don't map to pojo fields. 您的json字段不会映射到pojo字段。 So you need to annotate your POJO fields with @JsonProperty("Level2") @JsonProperty("genericObject") and so on. 因此,您需要使用@JsonProperty("Level2") @JsonProperty("genericObject")来注释POJO字段。

So your deserialization code should look like 所以您的反序列化代码应该看起来像

ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);

JavaType javaType = TypeFactory.defaultInstance()
         .constructParametricType(Level1.class, c);

mapper.readValue(json, javaType);

And classes look like 和类看起来像

class Level1<T> {
    @JsonProperty("Level2")
    public Level2<T> l2;
}
class Level2<T> {
    @JsonProperty("Level3")
    public Level3<T> l3;
}
class Level3<T> {
    @JsonProperty("genericObject")
    public List<T> objectsList;
}

And here is full working gist demo 这是完整的工作原理演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM