2017-02-19 200 views
0

我試圖將一些json元素映射到java對象,但似乎無法找出正確的方法。那裏有很明顯的例子負荷在線上如何映射JSON來的POJO,但我有一個大的JSON字符串,我只希望映射一個JSON字符串的幾個鍵來建立一個對象...將JSON映射到Java的正確方法對象

{ 
"glossary": { 
    "title": "example glossary", 
    "GlossDiv": { 
     "title": "S", 
     "GlossList": { 
      "GlossEntry": { 
       "ID": "SGML", 
       "SortAs": "SGML", 
       "GlossTerm": "Standard Generalized Markup Language", 
       "Acronym": "SGML", 
       "Abbrev": "ISO 8879:1986", 
       "GlossDef": { 
        "para": "A meta-markup language, used to create markup languages such as DocBook.", 
        "GlossSeeAlso": ["GML", "XML"] 
       }, 
       "GlossSee": "markup" 
      } 
     } 
    } 
} 

}

可以說,我只希望標題和GlossEntry:ID,SortAs和縮略,

什麼是最乾淨的,爲什麼把它映射到只有這些領域一個POJO,而不必全JSON映射到一個對象,並得到那些元素

+1

您首先必須選擇一個映射器。它們並不都具有相同的功能。但是我懷疑你會找到一個允許你跳過中級GlossDiv和GlossList對象的程序,除非你自己編寫低級分析代碼來自定義這個映射程序。如果您準備好了,那麼您可以簡單地使用通用的JSON解析器(即返回JSONObjects或Maps),並從中提取信息。 –

+0

嘿歡呼,這就是我在想什麼,但不知道這是否是正確的方法。也許足智多謀將整個json字符串轉換爲對象並根據需要獲取元素 – rogger2016

+2

在性能問題出現之前不要進行優化,並且您已經證明此性能問題來自解析該JSON。不成熟的優化是萬惡之源。 –

回答

2

如果您打算使用Jackson這款流行的適用於Java的JSON解析器,該answer可能會爲您提供一些見解。這是針對您的問題量身定製的解決方案。

首先定義一個類爲以下的值保持:

@JsonIgnoreProperties(ignoreUnknown = true) 
public class GlossaryEntry { 

    @JsonProperty("ID") 
    private String id; 

    @JsonProperty("SortAs") 
    private String sortAs; 

    @JsonProperty("Abbrev") 
    private String abbrev; 

    // Constructor, getters and setters omitted 
} 

然後分析整個JSON成JsonNodeObjectMapper

String json = "{\"glossary\":{\"title\":\"example glossary\",\"GlossDiv\":{\"title\":\"S\",\"GlossList\":{\"GlossEntry\":{\"ID\":\"SGML\",\"SortAs\":\"SGML\",\"GlossTerm\":\"Standard Generalized Markup Language\",\"Acronym\":\"SGML\",\"Abbrev\":\"ISO 8879:1986\",\"GlossDef\":{\"para\":\"A meta-markup language, used to create markup languages such as DocBook.\",\"GlossSeeAlso\":[\"GML\",\"XML\"]},\"GlossSee\":\"markup\"}}}}}"; 

ObjectMapper mapper = new ObjectMapper(); 
JsonNode tree = mapper.readTree(json); 

使用JSON Pointer查詢爲GlossEntry節點和最後使用ObjectMapper解析爲GlossaryEntry實例:

JsonNode node = tree.at("/glossary/GlossDiv/GlossList/GlossEntry"); 
GlossaryEntry glossaryEntry = mapper.treeToValue(node, GlossaryEntry.class); 

JSON Pointer是遍歷JSON的路徑語言。有關更多詳細信息,請檢查RFC 6901。從2.3版本開始,它在Jackson中可用。

+0

嘿,這是一個很好的例子,但是如果在一個完全不同的節點中也有一個「ID」,也就是根「詞彙表」也有一個ID ......再次爲回覆而歡呼:) – rogger2016

+1

@ rogger2016那麼,這個解決方案是爲了解決你在問題中提供的情況,你是否還需要根節點的ID(如果存在的話)? –

+0

是的,我可能很快會遇到這種情況。例如,如果ID在不同的節點「glossA/ID」,另一個註釋將是「GlossB/ID」....不確定 – rogger2016

1

使用Google gson library您可以將json映射到通用的JsonElement。從那裏你可以訪問字段並遍歷子對象。

JsonElement elem = new JsonParser.parse(input); 

這越來越複雜,你需要更多的領域。我建議構建一個反序列化DTO,提供正確的對象層次結構。然後你可以使用標準的映射方法來映射你的json。 在第二步中,您可以將此DTO映射到您自己的域模型。 像ModelMapper這樣的項目使得這項任務變得相當容易。