JsonPath访问嵌套对象数组元素异常求助
解决RestAssured JsonPath访问数组元素时的语法错误问题
问题背景
你尝试从包含数组和嵌套对象的JSON响应中提取od_pair、bucket编码和available数值,但在使用RestAssured的JsonPath访问元素时遇到了语法错误。
你的JSON响应如下:
[ { "od_pair":"7015400:8727100", "buckets":[ {"bucket":"C00","original":2,"available":2}, {"bucket":"A01","original":76,"available":0}, {"bucket":"B01","original":672,"available":480} ] }, { "od_pair":"7015400:8814001", "buckets":[ {"bucket":"C00","original":2,"available":2}, {"bucket":"A01","original":40,"available":40}, {"bucket":"B01","original":672,"available":672}, {"bucket":"B03","original":632,"available":632}, {"bucket":"B05","original":558,"available":558} ] } ]
你编写的测试方法以及遇到的错误:
public static void updateBuckets(String ServiceName, String DateOfJourney) throws Exception { File jsonExample = new File(System.getProperty("user.dir"), "\\LogAvResponse\\LogAvResponse.json"); JsonPath jsonPath = new JsonPath(jsonExample); List<Object> LegList = jsonPath.getList("$"); int NoofLegs = LegList.size(); System.out.println("No of legs :" + NoofLegs); for (int j = 0; j <= NoofLegs; j++) { String OD_Pair = jsonPath.param("j", j).getString("[j].od_pair"); System.out.println("OD Pair: " + OD_Pair); List<Object> BucketsList = jsonPath.param("j", j).getList("[j].buckets"); int NoOfBuckets = BucketsList.size(); System.out.println("no of Buckets: " + NoOfBuckets); for (int i = 0; i < NoOfBuckets; i++) { String BucketCode = jsonPath.param("j", j).param("i", i).getString("[j].buckets[i].bucket"); String Available = jsonPath.param("j", j).param("i", i).getString("[j].buckets[i].available"); int BucketCodeColumn = XLUtils.getBucketCodeColumn(BucketCode); int ServiceRow = XLUtils.getServiceRow(ServiceName, DateOfJourney, OD_Pair); System.out.println("Row of " + ServiceName + ":" + DateOfJourney + "is:" + ServiceRow); System.out.println("Bucket Code column of " + BucketCode + " is: " + BucketCodeColumn); XLUtils.updateAvailability(ServiceRow, BucketCodeColumn, Available); } } }
错误信息:
Caused by: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script1.groovy: 1: unexpected token: [ @ line 1, column 27.
restAssuredJsonRootObject.[j].od_pair
错误原因分析
- JsonPath参数化语法错误:你直接在路径中写
[j],但RestAssured的JsonPath参数需要用{}来包裹参数名,比如{j},而不是把变量直接放在方括号里。 - 循环边界越界:
for (int j = 0; j <= NoofLegs; j++)会导致数组越界,因为数组索引从0开始,最大索引是NoofLegs - 1,所以应该用j < NoofLegs。
修正后的代码
这里是修复后的完整方法,我标注了关键修改点:
public static void updateBuckets(String ServiceName, String DateOfJourney) throws Exception { File jsonExample = new File(System.getProperty("user.dir"), "\\LogAvResponse\\LogAvResponse.json"); JsonPath jsonPath = new JsonPath(jsonExample); List<Object> LegList = jsonPath.getList("$"); int NoofLegs = LegList.size(); System.out.println("No of legs :" + NoofLegs); // 修正1:循环边界改为j < NoofLegs,避免越界 for (int j = 0; j < NoofLegs; j++) { // 修正2:用{j}代替[j]来引用参数 String OD_Pair = jsonPath.param("j", j).getString("{j}.od_pair"); System.out.println("OD Pair: " + OD_Pair); // 修正3:同样用{j}参数化数组索引 List<Object> BucketsList = jsonPath.param("j", j).getList("{j}.buckets"); int NoOfBuckets = BucketsList.size(); System.out.println("no of Buckets: " + NoOfBuckets); for (int i = 0; i < NoOfBuckets; i++) { // 修正4:嵌套路径中用{j}和{i}分别引用两个循环的参数 String BucketCode = jsonPath.param("j", j).param("i", i).getString("{j}.buckets[{i}].bucket"); String Available = jsonPath.param("j", j).param("i", i).getString("{j}.buckets[{i}].available"); int BucketCodeColumn = XLUtils.getBucketCodeColumn(BucketCode); int ServiceRow = XLUtils.getServiceRow(ServiceName, DateOfJourney, OD_Pair); System.out.println("Row of " + ServiceName + ":" + DateOfJourney + " is:" + ServiceRow); System.out.println("Bucket Code column of " + BucketCode + " is: " + BucketCodeColumn); XLUtils.updateAvailability(ServiceRow, BucketCodeColumn, Available); } } }
额外优化建议
你还可以通过直接获取每个leg的Map对象来简化代码,避免重复使用参数化的JsonPath,让代码更易读:
public static void updateBuckets(String ServiceName, String DateOfJourney) throws Exception { File jsonExample = new File(System.getProperty("user.dir"), "\\LogAvResponse\\LogAvResponse.json"); JsonPath jsonPath = new JsonPath(jsonExample); // 直接获取数组中的每个对象为Map List<Map<String, Object>> legList = jsonPath.getList("$"); System.out.println("No of legs :" + legList.size()); for (Map<String, Object> leg : legList) { String odPair = (String) leg.get("od_pair"); System.out.println("OD Pair: " + odPair); // 获取当前leg下的buckets列表 List<Map<String, Object>> bucketsList = (List<Map<String, Object>>) leg.get("buckets"); System.out.println("no of Buckets: " + bucketsList.size()); for (Map<String, Object> bucket : bucketsList) { String bucketCode = (String) bucket.get("bucket"); String available = bucket.get("available").toString(); int BucketCodeColumn = XLUtils.getBucketCodeColumn(bucketCode); int ServiceRow = XLUtils.getServiceRow(ServiceName, DateOfJourney, odPair); System.out.println("Row of " + ServiceName + ":" + DateOfJourney + " is:" + ServiceRow); System.out.println("Bucket Code column of " + bucketCode + " is: " + BucketCodeColumn); XLUtils.updateAvailability(ServiceRow, BucketCodeColumn, available); } } }
这种方式不需要依赖JsonPath的参数化语法,直接通过Java集合操作来遍历JSON结构,代码逻辑更直观,也不容易出错。
内容的提问来源于stack exchange,提问作者Mihir




