背景:性能測試時,我們需要對上個請求返回的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());