背景:性能测试时,我们需要对上个请求返回的json数据提取里的一个子json做加工处理。子json可能是一个简单的json,也可能是一个json对象数组。根据不同的业务请求json数据。用jmeter自带的正则提取不是很好动态处理。
1、在http请求加BeanShell后置处理程序,输入以下代码。报如下错。
2019-11-28 09:55:00,678 ERROR o.a.j.u.BeanShellInterpreter: Error invoking bsh method: eval Sourced file: inline evaluation of: ``import org.apachejmeter.assertions; import org.apachejmeter.samples.SampleResult . . . '' : Typed variable declaration : Class: JSONObject not found in namespace
解决办法:通过maven去下载jar包,放到D:\tools\apache-jmeter-5.1.1\lib\ext 目录下,重启Jmeter即可解决。
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20190722</version>
</dependency>
2、在jmeter BeanShell上代码不是很好封装,最后选择在IEDA上使用fastjson做json处理。写好代码生成jar包,放到D:\tools\apache-jmeter-5.1.1\lib\ext里。通过参数去调jar里的类和方法。为了方便,类里的方法使用静态 公共的方法。
public static String para(String response_data){
JSONObject response_data_obj = JSONObject.parseObject(response_data);
Object data=response_data_obj.get("data");//.get("attack_data").get("animal_list").toString();
//Object data=response_data_obj.get("data").get("attack_data").get("animal_list").toString(); jmeter Beahshell里可以直接这样调,但是java IEDA工具里只能一层一层去获取json的key值。
//System.out.println(response_data);
//System.out.println(data.toString());
JSONObject attack_data_obj = JSONObject.parseObject(data.toString());
Object attack_data=attack_data_obj.get("attack_data");
// System.out.println("attack_data:"+attack_data.toString());
JSONObject animal_list_obj = JSONObject.parseObject(attack_data.toString());
Object animal_List_obj=animal_list_obj.get("animal_list");
//获取animal_list数组对象
JSONArray res = animal_list_obj.getJSONArray("animal_list");
List<Animal_list> rules = new ArrayList<Animal_list>();
for (int i = 0; i < res.size(); i++) {
JSONObject Animal_listi = (JSONObject) res.get(i);
Animal_list Animal_list1;
Animal_list1 = JSONObject.toJavaObject(Animal_listi,Animal_list.class);//把json转为java对象
rules.add(Animal_list1);
}
String s = rules.toString();
System.out.println(s);
return s;
Animal_list.class 基类,在这里自动给他多增加了一个属性。
package cn.oscar.game;
public class Animal_list {
private int id;
private int num;
private int type;
public Animal_list(int id, int num) {
this.id = id;
this.num = num;
this.type = 10;
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setNum(int num) {
this.num = num;
}
public int getNum() {
return num;
}
public void setType(int type) {
this.type = 10;
}
public int getType() {
return type;
}
@Override
public String toString() {
return "{\"id\":" + id + ",\"num\":" + num + ",\"type\":" + type + "}";
}
}
3、Jmeter Bean shell最终代码如下
import org.apachejmeter.assertions;
import org.apachejmeter.samples.SampleResult;
import org.apachejmeter.assertions.AssertionResult;
import cn.oscar.game.Test;String response_data =prev.getResponseDataAsString();
//JSONObject data_obj = new JSONObject(response_data);
log.info("res:"+response_data);data=Test.para(response_data); //这里data没有做对象申明,如果做了会导致第一次运行正常,循环第二次会报错。
vars.put("data_test",data.toString());