解决jmeter脚本调用removeAllArguments()后,同一线程多次循环时,第二次循环获取不了http取样器的请求报文的问题

本来写该脚本的目的是:对一个接口进行压测,编写压测脚本,由于接口需要签名和加密,需要在前置处理器做签名和加密,使得直接在http取样器的请求报文填写明文即可。这里有一个重要点就是在jmeter前置处理器替换原有请求报文,且兼容请求报文含有模板字符串${}的情况。

问题点:在前置处理器调用了sampler.getArguments().removeAllArguments();,若线程组配置中,进行了多次循环,不管你线程组配置了多少个线程,只要同一线程循环了1次以上,则在后续循环中,sampler.getArguments().getArgument(0)都会报空指针错误,也就无法再获取http取样器填写的请求报文。

备注:之所以要使用sampler.getArguments().removeAllArguments();,是因为要替换原有请求报文,之后会调用sampler.addNonEncodedArgument("", "这里传入新的请求体字符串", "");

解决方法:使用HTTP Request Defaults元器件,将该元器件移动至该HTTP取样器的子级,请求体写在HTTP Request Defaults元器件下。

前置处理器脚本:


import org.apache.jmeter.config.Arguments;



String newReqBody = "{\"hello\": \"sss\"}";



Arguments args= sampler.getArguments();
log.info("removeAllArguments调用前的args size: " + args.getArguments().size());


String requestBodyStr = args.getArgument(0).getValue(); // 当为POST请求时,只有一个参数,即请求体。
log.info("args0: ");
log.info(requestBodyStr);




sampler.getArguments().removeAllArguments();
//sampler.getArguments().removeArgument(0);
sampler.addNonEncodedArgument("", newReqBody, ""); //

Arguments args2 = sampler.getArguments();

log.info("removeAllArguments调用后的args size: size: " + args2.getArguments().size());
log.info("args2 toString: " + args.toString());

<think>好的,我现在需要帮助用户解决关于JMeter二次开发自定义取样器问题。用户提到想通过二次开发创建自定义取样器来处理HTTP请求,并且需要示例。首先,我应该回忆一下JMeter的扩展机制。JMeter允许用户通过编写自定义的Java类来扩展功能,比如取样器、监听器等。 接下来,用户提到了需要jar包,可能需要引用相关的依赖。根据用户提供的引用[1]和[2],他们之前遇到过缺少json.jar和jython的问题。所以,在开发自定义取样器,可能需要确保相关的依赖库被正确引,比如Apache的HttpClient库,或者JMeter的核心jar包。 然后,我需要考虑自定义取样器的基本结构。通常,自定义取样器需要继承AbstractJavaSamplerClient类,并实现其中的方法,比如setupTest、runTest等。在runTest方法中,可以编写发送HTTP请求的逻辑,使用HttpClient库来创建请求,设置方法(GET或POST),处理响应等。 用户可能需要一个具体的步骤,比如如何创建项目,添加依赖,编写代码,打包成jar,然后放到JMeter的lib/ext目录下。还需要提到测试和调试的方法,比如在JMeter中查看结果树来验证自定义取样器的效果。 另外,用户可能遇到的问题包括类路径错误、依赖缺失或者版本不兼容。例如,如果使用Maven管理依赖,需要确保JMeter的核心jar包版本与项目中的一致,否则可能导致运行错误。此外,打包可能需要将所有依赖打一个jar中,或者将依赖jar放在JMeter的lib目录下。 可能还需要考虑示例代码的结构,比如如何配置HTTP请求数,处理异常,以及如何将结果返回给JMeter。例如,在runTest方法中,需要返回SampleResult对象,设置响应数据、状态码等信息。 最后,用户可能需要验证自定义取样器是否正常工作,所以需要指导他们如何将jar包放正确的位置,启动JMeter,添加线程组和自定义取样器,并运行测试。同,提醒可能出现的常见错误,如ClassNotFound,这可能是因为依赖库没有正确放置。</think>### JMeter自定义取样器开发步骤 #### 一、环境准备 1. 创建Maven项目 ```xml <!-- pom.xml依赖配置 --> <dependency> <groupId>org.apache.jmeter</groupId> <artifactId>ApacheJMeter_core</artifactId> <version>5.6.3</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency> ``` 2. 确认JMeter安装目录下已包含: - `lib/ext`目录放置自定义jar包 - `lib`目录包含所有运行依赖(如`json.jar`等)[^1] #### 二、核心代码实现 ```java import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient; import org.apache.jmeter.samplers.SampleResult; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; public class CustomHttpSampler extends AbstractJavaSamplerClient { @Override public SampleResult runTest(JavaSamplerContext context) { SampleResult result = new SampleResult(); result.sampleStart(); try (CloseableHttpClient httpClient = HttpClients.createDefault()) { HttpGet request = new HttpGet("http://example.com/api"); result.setSuccessful(httpClient.execute(request).getStatusLine().getStatusCode() == 200); } catch (Exception e) { result.setSuccessful(false); result.setResponseMessage(e.getMessage()); } result.sampleEnd(); return result; } } ``` #### 三、部署与验证 1. 打包命令 ```bash mvn clean package ``` 2. 将生成的目标jar包(含依赖)拷贝至JMeter的`lib/ext`目录[^2] 3. JMeter界面操作流程: - 创建线程组 - 添加「Java请求取样器 - 选择`CustomHttpSampler`类 - 添加「查看结果树」监听器 #### 四、高级配置项 1. 数化请求URL: ```java String url = context.getParameter("targetUrl"); ``` 2. 添加请求头: ```java request.addHeader("Content-Type", "application/json"); ``` 3. 处理POST请求: ```java HttpPost post = new HttpPost(url); StringEntity entity = new StringEntity("{\"key\":\"value\"}"); post.setEntity(entity); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值