2015-05-11 79 views
6

我試圖使用MOXY一個JSON具有以下結構來解組:JAXB:解組異質陣列

[ 
    { 
    "page": 1, 
    "pages": 1 
    }, 
    [ 
    { 
     "indicator": { 
      "id": "IC.BUS.EASE.XQ", 
      "value": "Ease of doing business index" 
     }, 
     "country": { 
      "id": "1A", 
      "value": "Arab World" 
     }, 
     "value": "113.952380952381", 
     "date": "2014" 
    }, 
    ... 
    ] 
] 

陣列的第一個元素是一個對象和第二元件是複雜的元件的另一陣列。我真的在SO和MOXY文檔中找到了一個沒有任何成功的類似例子。

我將json文檔映射到JAVA類的最佳嘗試如下。根類是CountryDataResponse(干將& setter方法中省略):

@XmlRootElement 
@XmlType(propOrder ={"paginationInfo", "dataArray"}) 
public class CountryDataResponse { 
    private DataArray dataArray; 
    private PaginationInfo paginationInfo; 
} 

(我可以看到這個是要失敗的,因爲它不是一個數組,但我完全地丟失)

PaginationInfo類爲根數組的第一個元素建模,DataArray類包裝第二個元素,它是一個Data類元素數組。另外,我爲每個Data元素中的複雜類型創建了Indicator和Country類。

主要類別(指標和國家中省略):

@XmlRootElement(name = "paginationInfo") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class PaginationInfo { 

    private int page; 
    private int pages; 
} 

@XmlRootElement(name = "dataArray") 
public class DataArray { 
    List<Data> datas; 
} 

@XmlRootElement(name="data") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Data { 
    private Indicator indicator; 
    private Country country; 
    private String date; 
    private double value; 
} 

現在,調試以下代碼:

public static void main(String args[]) { 
    String test = "[{\"page\": 1,\"pages\": 1,\"per_page\": \"1000\",\"total\": 248}," 
       + "[" 
       + "{\"indicator\": {\"id\": \"NY.GDP.MKTP.CD\",\"value\": \"GDP (current US$)\"}," 
       + "\"country\": {\"id\": \"1A\",\"value\": \"Arab World\"}," 
       + "\"value\": \"2853079422103.94\"," 
       + "\"decimal\": \"1\"," 
       + "\"date\": \"2013\"}," 
       + "{\"indicator\": {\"id\": \"NY.GDP.MKTP.CD\",\"value\": \"GDP (current US$)\"}," 
       + "\"country\": {\"id\": \"S3\",\"value\": \"Caribbean small states\"}," 
       + "\"value\": \"67033118185.1864\"," 
       + "\"decimal\": \"1\"," 
       + "\"date\": \"2013\"}" 
       + "]]"; 

    JAXBContext jc = JAXBContext.newInstance(CountryDataResponse.class, Country.class, Data.class, DataArray.class, Indicator.class, PaginationInfo.class); 
    Unmarshaller unmarshaller = jc.createUnmarshaller(); 
    unmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON); 
    unmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, false); 

    Object res = unmarshaller.unmarshal(json, CountryDataResponse.class); 
} 

res對象(類JAXBElement)具有值類型ArrayList。陣列第一元件類CountryDataResponse的目的(它應該PaginationInfo),第二是另一個的ArrayListCountryDataResponse,太的元件(它們應該是數據實例)。

任何人都可以幫助我,或者它只是一個畸形的json,它不能自動正確解組?

預先感謝您。

回答

0

感謝2.6版中添加的MOXy功能,可以從javax.json.JsonStructure,javax.json.JsonObject和javax.json.JsonArray解組。

使用此功能我已經設法將原始JSON的不同部分解組爲兩個對象:PaginationInfo實例和DataList的ArrayList。然後可以使用這些對象來配置CountryDataResponse的一個實例,儘管它不是必需的,因爲這個類只是爲了直接從JSON解組而創建的。

public static CountryDataResponse javaSevenMode(String jsonString) 
    throws PropertyException, JAXBException { 

    Unmarshaller unmarshaller = JAXB_CONTEXT.createUnmarshaller(); 
    unmarshaller.setProperty(UnmarshallerProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON); 
    unmarshaller.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT, false); 

    StringReader sr = new StringReader(jsonString); 
    JsonReader jsonReader = Json.createReader(sr); 
    JsonArray rootArray = jsonReader.readArray(); 

    JsonObject paginationInfoJO = rootArray.getJsonObject(0); 
    JsonStructureSource paginationInfoJSS = new JsonStructureSource(paginationInfoJO); 
    PaginationInfo pi = unmarshaller.unmarshal(paginationInfoJSS, PaginationInfo.class).getValue(); 

    JsonArray dataJArray = rootArray.getJsonArray(1); 
    JsonStructureSource dataArrayJSS = new JsonStructureSource(dataJArray); 
    List<Data> datas 
      = (List<Data>) unmarshaller.unmarshal(dataArrayJSS, Data.class) 
      .getValue(); 

    DataArray da = new DataArray(); 
    da.setDatas(datas); 

    CountryDataResponse cdr = new CountryDataResponse(); 
    cdr.setDataArray(da); 
    cdr.setPaginationInfo(pi); 

    return cdr; 
} 

感謝@blaise-doughan靈感(見http://blog.bdoughan.com/2013/07/eclipselink-moxy-and-java-api-for-json.html

1

雖然JSON是有效的,我建議改變結構,東西線沿線的:

{ 
"paginationInfo": { 
    "page": 1, 
    "pages": 1 
}, 
"dataArray": [ 
    { 
     "indicator": { 
      "id": "IC.BUS.EASE.XQ", 
      "value": "Ease of doing business index" 
     }, 
     "country": { 
      "id": "1A", 
      "value": "Arab World" 
     }, 
     "value": "113.952380952381", 
     "date": "2014" 
    } 
] 

}

這將允許你提取您是否願意使用「鑰匙」名稱的數據這是如何使用JSON的。

另一種方法是嵌入分頁對象中的數據陣列:

{ 
"page": 1, 
"pages": 1, 
"dataArray": [ 
    { 
     "indicator": { 
      "id": "IC.BUS.EASE.XQ", 
      "value": "Ease of doing business index" 
     }, 
     "country": { 
      "id": "1A", 
      "value": "Arab World" 
     }, 
     "value": "113.952380952381", 
     "date": "2014" 
    } 
] 

}

這種方法將允許您創建一個通用頁包裝可能派上用場,如果你有多個您想要翻頁的格式。

希望這會有所幫助。

+0

謝謝您的回答。事實上,你的第一個建議是現在編組一個CountryDataResponse的結果,所以它會使用它很有意義:)不幸的是,我不能改變結構:它來自http://api.worldbank.org/國家/指示器/ NY.GDP.MKTP.CD?per_page = 1000&MRV = 1&格式= JSON。 – MrMiyagi

+1

在這種情況下,我會看看爲CountryDataResponse對象創建自定義序列化程序: http://www.baeldung.com/jackson-custom-serialization – robinsio