您的位置:首页 > 编程语言 > Java开发

JAVA嵌套解析Json字符串 - 递归方法

2017-09-15 14:09 1316 查看

1、需求

后台接口测试中,http request的response中data是json结构,数据较复杂,嵌套多层,类似于:
{
key1 : value1,
key2 : value2,
.............
keyT: [
{
key11: value11,
key12: value12,
......
keyA:   value1A,
......
keyB:   value1B,
.......
keyN: value1N
},
{
key11: value21,
key12: value22,
......
keyA:   value2A,
......
keyB:   value2B,
.......
keyN: value2N
},
.........
keyM: valueM,
}


目的:希望从层层嵌套的json串中,将里面的json数组中多组keyA,keyB对应的value抓取到,并成组配对打印到文件中。类似于:
keyA:value1A     keyB:value1B
keyA:value2A     keyB:value2B
..........
keyA:valueKA     keyB:valueKB

2、解题思路

网上Google了一把这类json嵌套解析的方法,有些源码实现较复杂,有些只是提供个思路,都不是很好。算了,自己来写吧。
最笨的方法是想抓什么数据,直接检索(类似于linux的grep的思路),但这种方式扩展性差,并且在json串较复杂时(如部分为空),检索结果容易有偏差。

为减少代码量,考虑用递归思路来做。

代码如下:

package testJa;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Iterator;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

//this class to analysis json via recursion
public class jsonOp {
public void jsonPattern(String inFile,String outFile,String patt) throws IOException, JSONException{
File fi = new File(inFile);
if(fi.isFile() && fi.exists()){
//read file
InputStreamReader in = new InputStreamReader(new FileInputStream(fi));
BufferedReader br = new BufferedReader(in);
String jsonStr = br.readLine(); //read by line
//write file
File fo = new File(outFile);
OutputStream out = new FileOutputStream(fo);

String [] pats = patt.split(":");
String [] pat_detail = pats[1].split(",");
JSONArray ja = getJsonArray(jsonStr,pats[0]); //get target json array

//get target items from json array via pattern
int len = ja.length();
for(int i=0;i<len;i++){
Object seatID = ja.getJSONObject(i).get(pat_detail[0]);
Object seatName = ja.getJSONObject(i).get(pat_detail[1]);
//write to output file
String outStr = "seatID: "+seatID+"\tseatName: "+seatName+"\r\n";
byte[] by = outStr.getBytes();
out.write(by);
}
br.close();
in.close();
out.close();
}
}

public JSONArray getJsonArray(String jsonStr, String listKey){
if(jsonStr.equals("")){
return null;
}
Character c = jsonStr.charAt(0);
if(c == '{'){
try {
JSONObject jo = new JSONObject(jsonStr);
Iterator it = jo.keys();
while(it.hasNext()){
String key = (String)it.next();
if(key.equals(listKey)){
return jo.getJSONArray(key);
}else{
String value = jo.get(key).toString();
JSONArray ja = getJsonArray(value,listKey); //recursion
if(ja!=null){
return ja;
}
}
}//end while
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return null;
}
}
return null;
}

public static void main(String [] args) throws IOException, JSONException{
String inFile = "/Users/xx/Downloads/tmp/seatidseatname.txt";
String outFile= "/Users/xx/Downloads/tmp/out.txt";
String patt = "seats:seatID,seatName";
jsonOp jo = new jsonOp();
jo.jsonPattern(inFile, outFile, patt);

}
}

代码解读:

1. main中给出了个实例,其中“patt”中存放要匹配的串,seats是jsonArray对应的key,seatID,seatName是jsonArray中的每个json体中抽取的key
String patt = "seats:seatID,seatName";

2. 为简单期间,输入和输出都从文件中读取,有需要的可以把输入文件砍掉,直接读入是个String即可
String inFile = "/Users/xx/Downloads/tmp/seatidseatname.txt";
String outFile= "/Users/xx/Downloads/tmp/out.txt";


其中输入文件中的值为:(飘红部分是要抓取的部分)

{"code":"0000","message”:”xx”,”data":{"scheduleID”:xx,”cinemaID”:”xx”,”showID”:”xx”,”currentTime”:xx,”hallName":"4","cinemaName”:”xx”,"openTime":"22:45:00","openDate":"2017-09-14","loverSeat":false,"mobile”:”xx”,"regular":false,"seats":[{"status":1,"seatID":"3661","topPx":42,"leftPx":175,"flag":0,"rowName":"A","seatName":"A01","column":0,"row":0},{"status":1,"seatID":"3662","topPx":42,"leftPx":208,"flag":0,"rowName":"A","seatName":"A02","column":0,"row":0},{"status":1,"seatID":"3787","topPx":386,"leftPx":505,"flag":0,"rowName":"L","seatName":"L11","column":0,"row":0},{"status":0,"seatID":"3788","topPx":386,"leftPx":538,"flag":0,"rowName":"L","seatName":"L12","column":0,"row":0}],"soldCount":21,"minTopPx":42,"maxLeftPx":538,"maxTopPx":386,"maxColumn":0,"minColumn":0,"maxRow":0,"minRow":0}}}

3、getJsonArray函数是递归函数
要注意,递归函数的特点,获取目标值后需从递归函数(层层堆栈结构)中退出,所以在递归函数的调用后需要有判断进行退出:
JSONArray ja = getJsonArray(value,listKey); //recursion
if(ja!=null){
return ja;
}
如果没有这个条件判断,返回值是有问题的。

END
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 递归 json