本文介绍了Java FastXML JSON库:如何解析嵌套的JSON结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 以下是我正在尝试使用org.fasterxml.jackson.core和jackson-databind库以流方式测试JSON处理的Java程序。 目标是学习如何处理JSON并捕获我想要的信息。目前,我想要完成的是: 1)我在这里发布的JSON有很多数据。遵循此JSON的Java程序是我尝试处理此JSON,特别是捕获name:part1 / myAnalysis / matches 下的US SSN元素以及名称:MasterCard信用卡号,这两个元素都属于 part1 / myAnalysis / matches 的范围。的 ONLY 即可。 好​​的,现在,我的目标是: 我只想让我的程序编译并至少打印出那些感兴趣的那两个元素(前面提到的那些元素)我 我的编译尝试产生了以下结果: 未处理的属性:类型未处理的属性:incidentTimestamp 未处理的属性:numOfMatches 未处理的属性:myReport 未处理的属性:whatSetItOffEntry 未处理的属性:seeRestrictedIds 未处理的属性:status 未处理的属性:timeStamps 未处理的属性:count 因此,程序试图处理的JSON如下。如果有人可以指出如何编译这个程序,然后打印出我想要的元素。这将是一个很好的两步过程任务。 {type:ImportantIncidentInfo,incidentTimestamp:2014-05-15T10 :09:27.989-05:00,numOfMatches:4,myReport:{docReports:{part1 /。:{path:[unknown],myAnalysis:{匹配:[{id:{major:1,minor:0},name:US SSN,position:13,string:636-12-4567}, {id:{major:3, minor:0},name:MasterCard信用卡号,位置:35,string:5424-1813-6924-3685}]},cleaningUpData:[{startPosition :0,endPosition:65,frameContent:}],minedMetadata:{Content-Encoding:ISO-8859-1,Content-Type:text / html; charset = iso-8859-1},deducedMetadata:{Content-Type:text / html; iso-8859-1}},part2 /。:{path:[unknown],patternAnalysis:{匹配:[{id:{major:1,minor :0},name:SSN,position:3,string:636-12-4567 \ r},{id:{major:3,minor :0},名称:万事达卡信用卡号,位置:18,字符串:\ n5424-1813-6924-3685 \ r}]},已清理过的ata:[{startPosition:0,endPosition:44,frameContent:}],minedMetadata:{Content-Encoding:windows-1252,Content-Type:文本/无格式; charset = windows-1252},deducedMetadata:{Content-Type:text / plain; iso-8859-1}}}},whatSetItOffEntry:{action:Log,component:{type:aComponent,components:[{type:PatternComponent ,patterns:[1],not:false}],not:false},ticketInfo:{createIncident:true,tags:[],seeRestrictedIds:[{type :userGroup,name:SiteMasters,description:SiteMaster组,主人:[04fb02a2bc0fba],成员:[],id:04fade}] },letmeknowInfo:{createNotification:true,contactNames:[ [email protected]]}},seeRestrictedIds:[04fade66c0],status:New,timeStamps:[2014-03-15T10:09:27.989-05:00] ,count:1} 任务#2 2)为了处理这个JSON,我编写了以下Java程序。 import com.fasterxml.jackson.databind。*; import com.fasterxml.jackson.core。*; import java.io. *; 公共类ParseJson { public static void main(String [] args){ try { / / TODO自动生成的方法stub JsonFactory f = new MappingJsonFactory(); // JsonParser jp = f.createJsonParser(new File(args [0])); JsonParser jp = f.createParser(new File(C:/ somepath /in/my/eclipse/project/jsonFormattedModified.json)); JsonToken当前; current = jp.nextToken(); if(current!= JsonToken.START_OBJECT){ System.out.println(错误:root应该是对象:quiting。); 返回; } while(jp.nextToken()!= JsonToken.END_OBJECT){ String fieldName = jp.getCurrentName(); //从字段名移到字段值 current = jp.nextToken(); if(fieldName.equals(matches)){ if(current == JsonToken.START_ARRAY){ //对于数组中的每条记录while( jp.nextToken()!= JsonToken.END_ARRAY){ //将记录读入树模型, //这会将解析位置移动到它的结尾 JsonNode node = jp .readValueAsTree(); //现在我们可以随机访问对象 System.out.println(Name:+ node.get(name)。asText()); System.out.println(POS:+ node.get(pos)。asText()); } } else { System.out.println(错误:记录应该是一个数组:跳过。); jp.skipChildren(); } } else { System.out.println(Unprocessed property:+ fieldName); jp.skipChildren(); } } } catch(IOException ie){ ie.printStackTrace(); } } } 感谢您的帮助。解决方案需要考虑的两件事: / p> 如果你想保持流式传输,调用 jp.readValueAsTree()不是好主意,因为它将分配内存以创建具有当前节点下所有数据的树(在您的代码中,匹配下的所有内容),除非您确定这是一棵小树。 要获取数组中的值,不需要先创建数组。流API将让您走到所需数组中的值。 正如@MChaker在他的回答中所示,如果您需要JSON文件中提供的大多数数据,创建一个模型来保存数据将是有益的。但如果你只需要一些价值观,杰克逊会让你这样做。尽管如此,我必须承认,以真正的流媒体方式获取数据需要一些创造力来找到跟踪你的位置以及你期望的数据的方法。 以下代码显示简单的方法和流媒体方式: import java.io. *; import java.util。*; import com.fasterxml.jackson.core。*; import com.fasterxml.jackson.databind。*; / ** * http://stackoverflow.com/q/30288878/3080094 *使用jackson-databind-2.5.3使用 * jackson -annotations-2.5.0和 * jackson-core-2.5.3 * @author vanOekel * / 公共类JsonTest { public static void main(String [] args){ try { new JsonTest()。getNames(); } catch(例外e){ e.printStackTrace(); } } ObjectMapper jsonMapper = new ObjectMapper(); JsonFactory jsonFactory = new JsonFactory(); void getNames()throws Exception { final String resourceName =some.json; JsonNode jn; try(InputStream in = Thread.currentThread()。getContextClassLoader()。getResourceAsStream(resourceName)){ if(in == null){ throw new FileNotFoundException(找不到文件:+ resourceName); } jn = jsonMapper.readTree(in); } findByPath(jn); try(InputStream in = Thread.currentThread()。getContextClassLoader()。getResourceAsStream(resourceName)){ if(in == null){抛出新的FileNotFoundException(找不到文件:+ resourceName); } JsonParser jsonParser = jsonFactory.createParser(in); findInStream(jsonParser); } } final String [] path = new String [] {myReport,docReports,part1 /。,myAnalysis,匹配 , 名称}; void findByPath(JsonNode jn){ JsonNode matchesNamesNode = jn; for(int i = 0; i< path.length - 1; i ++){ matchesNamesNode = matchesNamesNode.path(path [i]); } if(matchesNamesNode.isMissingNode()){抛出新的RuntimeException(没有找到名字的节点。); } System.out.println(树名:+ matchesNamesNode.findValuesAsText(path [path.length - 1])); } void findInStream(JsonParser jp)抛出异常{ int pathIndex = 0; List< String> names = new ArrayList< String>(); boolean breakOnClose = false; while(jp.nextToken()!= null){ final String fieldName = jp.getCurrentName(); if(fieldName == null){ continue; } if(breakOnClose&& fieldName.equals(path [path.length - 2])){ System.out.println(在节点末尾停止搜索+ fieldName的); 休息; } if(jp.getCurrentToken()!= JsonToken.FIELD_NAME){ continue; } // System.out.println(Field+ fieldName); if(pathIndex> = path.length - 1){ if(fieldName.equals(path [path.length - 1])){ //从字段名移到字段值。 jp.nextToken(); String name = jp.getValueAsString(); if(name == null){抛出新的RuntimeException(字段没有值+ fieldName); } names.add(name); System.out.println(Found+ fieldName +value:+ name); } } else if(fieldName.equals(path [pathIndex])){ System.out.println(Found node+ path [pathIndex]); pathIndex ++; if(pathIndex> = path.length - 1){ System.out.println(寻找名字......); breakOnClose = true; //防止破坏匹配值json-token。 jp.nextFieldName(); } } } System.out.println(流名称:+名称); } } The following here under is a Java program I am trying out to test JSON Processing using the org.fasterxml.jackson.core and the jackson-databind libraries in a streaming manner. The goal is to learn how to process JSON and capture the information I want. For now, what I want to accomplish is the following:1) The JSON that I post here under has a lot of data. The Java program that follows this JSON is my attempt to process this JSON and in particular, capture the "name": US SSN" element under "part1/myAnalysis/matches." and also "name": MasterCard Credit Card number", both elements falling under the the scope of "part1/myAnalysis/matches." ONLY.Okay, for now, My Goal is: I just want my program to compile and atleast print out those two elements (the ones aforementioned) that interest me.My attempt at compilation yielded the following results:Unprocessed property: typeUnprocessed property: incidentTimestampUnprocessed property: numOfMatchesUnprocessed property: myReportUnprocessed property: whatSetItOffEntryUnprocessed property: seeRestrictedIdsUnprocessed property: statusUnprocessed property: timeStampsUnprocessed property: countSo the JSON, the program is attempting to process is as under. If anyone can point out how to make this program compile and then print out the elements I want. That will be a great 2 step process Task.{ "type": "ImportantIncidentInfo", "incidentTimestamp": "2014-05-15T10:09:27.989-05:00", "numOfMatches": 4, "myReport": { "docReports": { "part1/.": { "path": [ "unknown" ], "myAnalysis": { "matches": [ { "id": { "major": 1, "minor": 0 }, "name": "US SSN", "position": 13, "string": " 636-12-4567 " }, { "id": { "major": 3, "minor": 0 }, "name": "MasterCard Credit Card Number", "position": 35, "string": " 5424-1813-6924-3685 " } ] }, "cleanedUpData": [ { "startPosition": 0, "endPosition": 65, "frameContent": "" } ], "minedMetadata": { "Content-Encoding": "ISO-8859-1", "Content-Type": "text/html; charset=iso-8859-1" }, "deducedMetadata": { "Content-Type": "text/html; iso-8859-1" } }, "part2/.": { "path": [ "unknown" ], "patternAnalysis": { "matches": [ { "id": { "major": 1, "minor": 0 }, "name": "SSN", "position": 3, "string": " 636-12-4567\r" }, { "id": { "major": 3, "minor": 0 }, "name": "MasterCard Credit Card Number", "position": 18, "string": "\n5424-1813-6924-3685\r" } ] }, "cleanedUpData": [ { "startPosition": 0, "endPosition": 44, "frameContent": "" } ], "minedMetadata": { "Content-Encoding": "windows-1252", "Content-Type": "text/plain; charset=windows-1252" }, "deducedMetadata": { "Content-Type": "text/plain; iso-8859-1" } } } }, "whatSetItOffEntry": { "action": "Log", "component": { "type": "aComponent", "components": [ { "type": "PatternComponent", "patterns": [ 1 ], "not": false } ], "not": false }, "ticketInfo": { "createIncident": true, "tags": [], "seeRestrictedIds": [ { "type": "userGroup", "name": "SiteMasters", "description": "Group for SiteMasters", "masters": [ "04fb02a2bc0fba" ], "members": [], "id": "04fade" } ] }, "letmeknowInfo": { "createNotification": true, "contactNames": [ "[email protected]" ] } }, "seeRestrictedIds": [ "04fade66c0" ], "status": "New", "timeStamps": [ "2014-03-15T10:09:27.989-05:00" ], "count": 1}Task # 22) To process this JSON, I wrote the following Java program. import com.fasterxml.jackson.databind.*;import com.fasterxml.jackson.core.*;import java.io.*;public class ParseJson { public static void main(String[] args) { try{ // TODO Auto-generated method stub JsonFactory f = new MappingJsonFactory(); //JsonParser jp = f.createJsonParser(new File(args[0])); JsonParser jp = f.createParser(new File("C:/somepath /in/my/eclipse/project/jsonFormattedModified.json")); JsonToken current; current = jp.nextToken(); if (current != JsonToken.START_OBJECT) { System.out.println("Error: root should be object: quiting."); return; } while (jp.nextToken() != JsonToken.END_OBJECT) { String fieldName = jp.getCurrentName(); // move from field name to field value current = jp.nextToken(); if (fieldName.equals("matches")) { if (current == JsonToken.START_ARRAY) { // For each of the records in the array while (jp.nextToken() != JsonToken.END_ARRAY) { // read the record into a tree model, // this moves the parsing position to the end of it JsonNode node = jp.readValueAsTree(); // And now we have random access to everything in the object System.out.println("Name: " + node.get("name").asText()); System.out.println("POS: " + node.get("pos").asText()); } } else { System.out.println("Error: records should be an array: skipping."); jp.skipChildren(); } } else { System.out.println("Unprocessed property: " + fieldName); jp.skipChildren(); } } } catch(IOException ie) { ie.printStackTrace(); } }}Thanks for all the help. 解决方案 Two things to consider:If you want to keep streaming, calling jp.readValueAsTree() is not a good idea as that will allocate memory to create the tree with all data under the current node (in your code, everything under "matches"), unless you know for sure this is a small tree.To get to a value in an array, there is no need to create an array first. The streaming API will let you walk to the value in the array you need.As @MChaker shows in his answer, if you need most of the data provided in the JSON file, creating a model to hold the data will be beneficial. But if you just need a couple of values, Jackson will let you do that. Allthough, I must admit, getting data in a truly streaming fashion will require some creativity to find ways of keeping track of where you are and what data you expect.Following code shows the easy way and the streaming way:import java.io.*;import java.util.*;import com.fasterxml.jackson.core.*;import com.fasterxml.jackson.databind.*;/** * http://stackoverflow.com/q/30288878/3080094 * Using jackson-databind-2.5.3 which uses * jackson-annotations-2.5.0 and * jackson-core-2.5.3 * @author vanOekel */public class JsonTest { public static void main(String[] args) { try { new JsonTest().getNames(); } catch (Exception e) { e.printStackTrace(); } } ObjectMapper jsonMapper = new ObjectMapper(); JsonFactory jsonFactory = new JsonFactory(); void getNames() throws Exception { final String resourceName = "some.json"; JsonNode jn; try (InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(resourceName) ) { if (in == null) { throw new FileNotFoundException("File not found: " + resourceName); } jn = jsonMapper.readTree(in); } findByPath(jn); try (InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(resourceName) ) { if (in == null) { throw new FileNotFoundException("File not found: " + resourceName); } JsonParser jsonParser = jsonFactory.createParser(in); findInStream(jsonParser); } } final String[] path = new String[] {"myReport", "docReports", "part1/.", "myAnalysis", "matches", "name"}; void findByPath(JsonNode jn) { JsonNode matchesNamesNode = jn; for (int i = 0; i < path.length - 1; i++) { matchesNamesNode = matchesNamesNode.path(path[i]); } if (matchesNamesNode.isMissingNode()) { throw new RuntimeException("No node with names found."); } System.out.println("Tree names: " + matchesNamesNode.findValuesAsText(path[path.length - 1])); } void findInStream(JsonParser jp) throws Exception { int pathIndex = 0; List<String> names = new ArrayList<String>(); boolean breakOnClose = false; while (jp.nextToken() != null) { final String fieldName = jp.getCurrentName(); if (fieldName == null) { continue; } if (breakOnClose && fieldName.equals(path[path.length - 2])) { System.out.println("Stopping search at end of node " + fieldName); break; } if (jp.getCurrentToken() != JsonToken.FIELD_NAME) { continue; } // System.out.println("Field " + fieldName); if (pathIndex >= path.length - 1) { if (fieldName.equals(path[path.length - 1])) { // move from field name to field value. jp.nextToken(); String name = jp.getValueAsString(); if (name == null) { throw new RuntimeException("No value exists for field " + fieldName); } names.add(name); System.out.println("Found " + fieldName + " value: " + name); } } else if (fieldName.equals(path[pathIndex])) { System.out.println("Found node " + path[pathIndex]); pathIndex++; if (pathIndex >= path.length - 1) { System.out.println("Looking for names ..."); breakOnClose = true; // prevent breaking on "matches" value json-token. jp.nextFieldName(); } } } System.out.println("Streaming names: " + names); }} 这篇关于Java FastXML JSON库:如何解析嵌套的JSON结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
09-02 18:05