2017-10-16 114 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