2017-10-16 105 views
0

我一直在尝试各种解决方案来得到这个工作。但没有成功。解析JSON深入嵌套通用与杰克逊

我有几类这样

class Level1<T> { 

    public Level2<T> l2; 
} 

class Level2<T> { 

    public Level3<T> l3; 
} 

class Level3<T> { 

    public List<T> objectsList; 
} 

牛逼在这种情况下可以是任何对象,并应尽可能是运行期间解析。

我的JSON是这样的:

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

的JSON属性“genericObject”更改其名称和属性取决于我收到该种类的对象。

我试着在我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?

回答

0

有迹象表明,你需要改变

  1. 1级的对象不是根对象几件事情,而是一个领域。如果你不想再创建一个包装对象,使用UNWRAP_ROOT_VALUE

    mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE); 
    
  2. 你不需要constructParametricType整个对象层次结构,只是构建它顶级链

    constructParametricType(Level1.class, genericObjectClass); 
    
  3. 你的json字段不映射到pojo字段。所以你需要用@JsonProperty("Level2")@JsonProperty("genericObject")等注释你的POJO字段。

所以,你的反串行化代码应该看起来像

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

+0

谢谢您的回答。但是我的意思是“genericObject”,是@JsonProperty在运行时会改变。因此我无法做类似@JsonProperty(“genericObject”)的事情,因为它可能是多种POJO。我会按照你的建议尝试TypeFactory,看它是否有效。谢谢! – alexluz

+0

@alexluz如果你的json中有不同的字段名称,那很好,也许你不需要为不同的POJO使用'@ JsonProperty'。但json字段名称需要与您想要反序列化的POJO完全相同。通用与否,他们需要匹配。如果你不能确保,那么你必须编写自定义的解串器。但是,在您发表评论之后,您似乎可以忽略这部分答案。 – varren