使用jackson将JSON解析为深度嵌套的泛型

时间:2017-10-16 10:00:24

标签: java json generics jackson nested-generics

我一直在尝试各种解决方案来实现这一目标。但没有成功。

我有几个这样的课程

class Level1<T> {

    public Level2<T> l2;
}

class Level2<T> {

    public Level3<T> l3;
}

class Level3<T> {

    public List<T> objectsList;
}

T 在这种情况下可以是任何对象,并且应该可以在运行时解析

我的JSON看起来像这样:

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

JSON属性&#34; genericObject&#34;根据我接收的对象类型更改其名称和属性。

我已经尝试在我的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);

尝试过的解决方案:

(de)serialising Nested Generics in Jackson

How to use Jackson with Generics

Is Jackson really unable to deserialize json into a generic type?

1 个答案:

答案 0 :(得分:0)

您需要更改一些内容

  1. Level1对象不是根对象,而是字段。如果您不想再创建一个包装器对象,请使用UNWRAP_ROOT_VALUE

    mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
    
  2. 对于整个对象层次结构,您不需要constructParametricType,只需为链中的顶级类构建它

    constructParametricType(Level1.class, genericObjectClass);
    
  3. 您的json字段未映射到pojo字段。因此,您需要使用@JsonProperty("Level2") @JsonProperty("genericObject")注释您的POJO字段,依此类推。

  4. 所以你的反序列化代码应该是

    ObjectMapper mapper = new ObjectMapper();
    mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
    
    JavaType javaType = TypeFactory.defaultInstance()
             .constructParametricType(Level1.class, c);
    
    mapper.readValue(json, javaType);
    

    课程看起来像

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

    这是完整的工作gist demo