2017-02-19 194 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这样的项目使得这项任务变得相当容易。