JMeter引入jsonpath.jar报错
JMeter中问题描述:
1、在jmeter中使用beanshell脚本时,使用 json-path-xxxxx.jar 解析json数据时会报错:
Error in method invocation: Static method read( java.lang.String, java.lang.String ) not found in class'com.jayway.jsonpath.JsonPath。
import com.jayway.jsonpath.JsonPath;
String s = prev.getResponseDataAsString();
String res = JsonPath.read(s,"$..idcard").toString();
log.info("-------------"+res);
具体报错:
2022-07-25 21:14:58,749 ERROR o.a.j.u.BeanShellInterpreter: Error invoking bsh method: eval Sourced file: inline evaluation of: ``import com.jayway.jsonpath.JsonPath; String s = prev.getResponseDataAsString(); . . . '' : Typed variable declaration : Error in method invocation: Static method read( java.lang.String, java.lang.String ) not found in class'com.jayway.jsonpath.JsonPath'
2022-07-25 21:14:58,749 WARN o.a.j.e.BeanShellPostProcessor: Problem in BeanShell script: org.apache.jorphan.util.JMeterException: Error invoking bsh method: eval Sourced file: inline evaluation of: ``import com.jayway.jsonpath.JsonPath; String s = prev.getResponseDataAsString(); . . . '' : Typed variable declaration : Error in method invocation: Static method read( java.lang.String, java.lang.String ) not found in class'com.jayway.jsonpath.JsonPath'
解决方案:
方案1:使用JSR223 - 选择 groovy 语音 ,方案来源:Jmeter JSR223 - Stack Overflow
优点:能够直接使用JsonPath包。
问题:jsonpath不能使用双引号,表达式里需要转义,与项目及异常的使用习惯不一致;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.Option;
import net.minidev.json.JSONArray;
String json = "{\"store\":{\"book\":[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":8.95},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":12.99},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":8.99},{\"category\":\"fiction\",\"author\":\"J. R. R. Tolkien\",\"title\":\"The Lord of the Rings\",\"isbn\":\"0-395-19395-8\",\"price\":22.99}],\"bicycle\":{\"color\":\"red\",\"price\":19.95}},\"expensive\":10}";
// String jsonPath = "$..book[?(@.author == 'Nigel Rees')].title";
String jsonPath = '$..book[?(@.author == \'Nigel Rees\')].title'
Configuration config = Configuration.defaultConfiguration().addOptions(Option.DEFAULT_PATH_LEAF_TO_NULL);
JSONArray authorsArr = JsonPath.using(config).parse(json).read(jsonPath);
System.out.println(authorsArr.get(0).toString());
方案2:编写代码,代码思路:类JsonUtil中的方法ParaseJson封装read方法,第一个参数是json字符串,第二个参数是jsonpath,将代码导出为jar包,包放入路径\apache-jmeter-5.0\lib\ext ,完美解决~
import com.jayway.jsonpath.JsonPath;
public class JsonUtil {
public String ParaseJson(String str,String paras){
String res = JsonPath.read(str,paras).toString();
return res;
}
}
这个解决方案的来源:jmeter下解决:beanshell 使用jsonpath解析json报错
作者百度网盘 jmeterUtil.jar,提取码:o0fr
小改造:在项目使用的时候,想获得的是一个列表,而不是string,再加多一个函数Read,直接返回JsonPath.read() 原装信息。
public class JsonUtil {
public String ParaseJson(String str,String paras){
String res = JsonPath.read(str,paras).toString();
return res;
}
public Object Read(String str, String paras){
Object document = Configuration.defaultConfiguration().jsonProvider().parse(str);
return JsonPath.read(document,paras);
}
}
使用例子:
import com.tool.JsonUtil;
JsonUtil jsonutil = new JsonUtil();
String responseString = "{\"code\":60000,\"msg\":\"OK\",\"data\":{\"token\":\"SRlzvZOkXLdH3sPsY5khwX90m3b8XZMHRLk2FDThD1uDe1LxeygglbCiUoll5a7nqIhSjXYfNO3J0toRDefimOMfxkPvBLkJUro78FJeFifDmJCeNB8FYtv2wDYAbCIj\",\"status\":1,\"accountType\":1,\"existSub\":false,\"authListUserInfoResList\":[{\"userId\":84569,\"userName\":\"uat-consult-admin\",\"accountType\":1,\"status\":1,\"isTrue\":true,\"roleList\":[{\"roleName\":\"管理员\",\"label\":\"administrator\"},{\"roleName\":\"回访管理员\",\"label\":\"revisit_admin\"},{\"roleName\":\"管理员\",\"label\":\"administrator\"},{\"roleName\":\"回访管理员\",\"label\":\"revisit_admin\"}]}],\"appid\":null,\"panshiUrl\":null}}";
String getJsonPath ="$..roleName";
String getJsonPathDate = jsonutil.ParaseJson(responseString,getJsonPath);
log.info("getJsonPathDate+++++++++++++++"+getJsonPathDate+"");
List aaa = jsonutil.Read(responseString,getJsonPath);
Set set = new LinkedHashSet(aaa);
List deduplicatedList = new ArrayList(set);
for (Object aa : deduplicatedList) {
log.info("----------------"+aa);
}
最后:
讲真,JMeter中中还是没搞懂这个问题根源。。。有明白的大佬请求赐教~
其他
DEA中引入json-path-xxx.jar错误的问题
如图,在项目中引入json-path包。
FileInputStream fis = new FileInputStream(file);
Map<String, Object> loaded = (Map<String, Object>) yaml.load(fis);
String header_str = new JSONObject(loaded).toString();
String data = JsonPath.read(header_str,"$.sit.adminun");
执行时提示:
Exception in thread "main" java.lang.NoClassDefFoundError: net/minidev/json/writer/JsonReaderI
at com.jayway.jsonpath.internal.DefaultsImpl.<init>(DefaultsImpl.java:17)
at com.jayway.jsonpath.internal.DefaultsImpl.<clinit>(DefaultsImpl.java:15)
at com.jayway.jsonpath.Configuration.getEffectiveDefaults(Configuration.java:43)
at com.jayway.jsonpath.Configuration.defaultConfiguration(Configuration.java:168)
at com.jayway.jsonpath.internal.ParseContextImpl.<init>(ParseContextImpl.java:21)
at com.jayway.jsonpath.JsonPath.read(JsonPath.java:550)
at com.functions.ReadYaml.main(ReadYaml.java:33)
Caused by: java.lang.ClassNotFoundException: net.minidev.json.writer.JsonReaderI
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 7 more
原因,如同网上所说,缺少相关依赖包!!!
因为我们是通过静态把包放到项目里,看不出调用json-path时他依赖了什么包,但是当通过Maven下载时,就发现带着下载了其他好几个包!!!再运行就没问题了~~
所以:需要把相关包集齐,或者通过maven下载~
初步结论,看来单纯引用json-path会报错,需要加依赖包。接下来,在讲下JMeter单纯通过引入 json-path包报错的问题。
参考:jmeter中引用jar包jsonpath的坎坷之路: - 走看看