2016-07-31 27 views
1

我使用Jackson API將json格式轉換爲Java對象模型。我正在使用Jaxsonxml 2.1.5解析器。 json響應如下所示。使用Jackson基於條件注入json屬性

{ 
    "response": { 
    "name": "states", 
    "total-records": "1", 
    "content": { 
    "data": { 
     "name": "OK", 
     "details": { 
     "id": "1234", 
     "name": "Oklahoma" 
     } 
    } 
    } 
} 
} 

現在json響應格式已經改變。如果total-records1,則details將是具有idname屬性的對象。但如果total-records超過1那麼details將對象的數組象下面這樣:

{ 
     "response": { 
     "name": "states", 
     "total-records": "4", 
     "content": { 
      "data": { 
      "name": "OK", 
      "details": [ 
       { 
       "id": "1234", 
       "name": "Oklahoma" 
       }, 
       { 
       "id": "1235", 
       "name": "Utah" 
       }, 
       { 
       "id": "1236", 
       "name": "Texas" 
       }, 
       { 
       "id": "1237", 
       "name": "Arizona" 
       } 
      ] 
      } 
     } 
     } 
    } 

我的Java類映射看起來像下面與早期json響應。

@JsonIgnoreProperties(ignoreUnknown = true) 
    public class MapModelResponseList { 

     @JsonProperty("name") 
     private String name; 

     @JsonProperty("total-records") 
     private String records; 

     @JsonProperty(content") 
     private Model model; 

     public Model getModelResponse() { 
     return model; 
     } 

     public void setModel(Model model) { 
     this.model = model; 
     } 
    } 

客戶端代碼

package com.test.deserializer; 

    import com.fasterxml.jackson.databind.DeserializationFeature; 
    import com.fasterxml.jackson.databind.ObjectMapper; 
    import com..schema.model.Person; 

    public class TestClient { 

     public static void main(String[] args) { 
      String response1="{\"id\":1234,\"name\":\"Pradeep\"}"; 
      TestClient client = new TestClient(); 
      try { 
       Person response = client.readJSONResponse(response1, Person.class); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 

     public <T extends Object> T readJSONResponse(String response, Class<T> type) { 
      ObjectMapper mapper = new ObjectMapper(); 
      mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT); 
      T result = null; 
      try { 
       result = mapper.readValue(response, type); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      return (T) result; 
     } 

    } 

現在基礎上,total-records如何處理對映射到任何Model對象的Model或列表。請告訴我。

回答

1

您需要一個自定義的反序列化器。這個想法是混合和匹配對象處理與樹處理。儘可能解析對象,但使用樹(JSONNode)進行自定義處理。

MapModelResponseList上,刪除records屬性並添加一個List<Data>數組,其中Data只是id /名稱對的持有者類。您可以通過返回此列表的大小來獲取總記錄。

在解串器,請執行下列操作:

public final class MapModelDeserializer extends BeanDeserializer { 
    public MapModelDeserializer(BeanDeserializerBase src) { 
    super(src); 
    } 

    protected void handleUnknownProperty(JsonParser jp, DeserializationContext ctxt, Object beanOrClass, String propName) throws IOException, JsonProcessingException { 
    if ("content".equals(propName)) { 
     MapModelResponseList response = (MapModelResponseList) beanOrClass; 

     // this probably needs null checks! 
     JsonNode details = (JsonNode) jp.getCodec().readTree(jp).get("data").get("details"); 

     // read as array and create a Data object for each element 
     if (details.isArray()) { 
     List<Data> data = new java.util.ArrayList<Data>(details.size()); 

     for (int i = 0; i < details.size(); i++) { 
      Data d = jp.getCodec().treeToValue(details.get(i), Data.class); 
      data.add(d); 
     } 

     response.setData(data); 
     } 
     // read a single object 
     else { 
     Data d = jp.getCodec().treeToValue(details, Data.class); 
     response.setData(java.util.Collections.singletonList(d)); 
     } 

    super.handleUnknownProperty(jp, ctxt, beanOrClass, propName); 
} 

請注意,你不執行deserialize() - 默認實現用於創建MapModelResponseList正常。 handleUknownProperty()用於處理content元素。由於超級調用中的@JsonIgnoreProperties(ignoreUnknown = true),您不關心的其他數據將被忽略。

+0

我收到一個錯誤,指出當使用上述方法時,com.fasterxml.jackson.databind.JsonMappingException:類com.test.deserializer.CustomDeserializer沒有默認(無arg)構造函數。 – zilcuanu

+0

在發佈的代碼中添加了一個構造函數。 – AngerClown

+0

我試着用你的方法。但仍然沒有運氣。讓我知道我的客戶代碼是否正確。我仍然得到相同的異常'com.fasterxml.jackson.databind.JsonMappingException:類com.test.deserializer.CustomDeserializer沒有默認(無arg)構造函數' – zilcuanu

相關問題