You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

JsonPath访问嵌套对象数组元素异常求助

解决RestAssured JsonPath访问数组元素时的语法错误问题

问题背景

你尝试从包含数组和嵌套对象的JSON响应中提取od_pairbucket编码和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


错误原因分析

  1. JsonPath参数化语法错误:你直接在路径中写[j],但RestAssured的JsonPath参数需要用{}来包裹参数名,比如{j},而不是把变量直接放在方括号里。
  2. 循环边界越界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

火山引擎 最新活动