Jmeter自定义函数

本文介绍了如何在JMeter中实现自定义函数,特别是针对Base64加密的需求。提供了两种方法,一种是通过Beanshell或BSF Sampler实现,另一种是开发JMeter插件,将Base64功能集成到JMeterPlugins.jar中,详细阐述了插件开发的步骤和所需文件。

Jmeter内置了一些常用的函数,在Jmeter->选项->函数助手对话框,但是测试过程中这些函数远远不够,

比如:对服务器返回的session信息MD5、Base64加密等,再上传给服务器,作为服务对客户端认证识别的过程。

因此经常需要在脚本引用或者实现自定义的函数。

方法一:

使用Beanshell Sampler、BSF Sampler等实现,现已Base64加密为例,脚本如下:


import sun.misc.BASE64Decoder;

String res = new sun.misc.BASE64Encoder().encode("${session}".getBytes());
vars.put("BASE64",res);


${session}:要加密的字符串参数

BASE64:加密后的字符串保存在${BASE64}参数中


方法二:

将Base64做成Jmeter的可以直接调用的函数,这需要用到Jmeter插件开发,为了简化开发,将Base64添加到已开发的JMeterPlugins.jar中

JMeterPlugins.jar下载地址:http://download.youkuaiyun.com/detail/meitingbee/8090373

官网也可以下载

步骤:
1、使用rar工具解压JMeterPlugins.jar
2、在相应目录Jmeter\functions下新建java文件Base64.java
3、在classpath中添加Base64.java引用的jar包
;%JAVA_HOME%/lib/ApacheJMeter_core.jar;%JAVA_HOME%/lib/ApacheJMeter_java.jar;%JAVA_HOME%/lib/sun.misc.BASE64Decoder.jar
4、使用javac编译java文件,生成Base64.class文件
javac  Base64.java
5、命令行使用jar打包
jar JMeterPlugins.jar kg
将kg包含的内容打包,包名JMeterPlugins.jar
6、将JmeterPlugins.jar复制到jmeter\lib\ext文件夹下,打开jmeter,函数助手中可以看到新增的_Base64函数

${__Base64(${session},)}即为${session}的Base64加密字符串

Base64.java文件内容如下:

package kg.apc.jmeter.functions;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import org.apache.jmeter.engine.util.CompoundVariable;
import org.apache.jmeter.functions.AbstractFunction;
import org.apache.jmeter.functions.InvalidVariableException;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.samplers.Sampler;
import org.apache.jmeter.threads.JMeterVariables;
import sun.misc.BASE64Encoder;

public class Base64 extends AbstractFunction
{
  private static final List<String> desc = new LinkedList();
  private static final String KEY = "__Base64";
  private Object[] values;

  public synchronized String execute(SampleResult paramSampleResult, Sampler paramSampler)
    throws InvalidVariableException
  {
    JMeterVariables localJMeterVariables = getVariables();
    String str1 = ((CompoundVariable)this.values[0]).execute();

    String str2 = new BASE64Encoder().encode(str1.getBytes());

    if ((localJMeterVariables != null) && (this.values.length > 1)) {
      String str3 = ((CompoundVariable)this.values[1]).execute().trim();
      localJMeterVariables.put(str3, str2);
    }

    return str2;
  }

  public synchronized void setParameters(Collection<CompoundVariable> paramCollection)
    throws InvalidVariableException
  {
    checkMinParameterCount(paramCollection, 1);
    this.values = paramCollection.toArray();
  }

  public String getReferenceKey()
  {
    return "__Base64";
  }

  public List<String> getArgumentDesc()
  {
    return desc;
  }

  static
  {
    desc.add("String to calculate Base64 hash");
    desc.add("Name of variable in which to store the result (optional)");
  }
}






<think>好的,用户现在想了解如何在JMeter中开发自定义函数,并且需要教程和示例代码。用户之前已经询问过相关问题,我之前也提供了详细的步骤和代码示例,但用户现在又引用了另一个资料,里面提到两种发送Java请求的方式,其中一种是JMeter函数二次开发,可能希望更详细的指导。 首先,我需要回顾之前的回答,确保不重复但覆盖所有必要点。之前的回答已经包含开发环境准备、核心代码实现、部署使用和调试技巧。用户引用的新资料提到需要继承AbstractFunction类,并且包名以functions结尾,这些在之前的示例中已经涵盖,可能需要强调这些关键点。 用户的新引用还提到依赖包的位置,比如lib和ext目录,这可能需要在环境准备部分进一步说明,确保用户正确添加依赖。此外,用户可能对包命名和类继承的具体要求有疑问,需要明确说明。 另外,用户可能对代码中的参数处理和线程安全有疑问,特别是自定义函数在多线程下的行为。之前的回答提到多线程并发问题在相关问题里,但可能需要更详细地解释如何确保线程安全,比如在execute方法中避免共享变量。 还需要注意示例代码的正确性,比如使用UUID生成随机字符串是否满足需求,或者是否需要更复杂的逻辑。同时,部署步骤中提到的重启JMeter函数助手调用是否正确,是否需要更多细节,比如如何找到函数助手的位置。 用户可能遇到的常见问题包括包结构错误、依赖缺失、未重启JMeter导致函数未加载,或者参数处理不正确。在回答中需要提前预警这些问题,并提供解决方法,比如检查日志、确认JAR位置等。 最后,确保回答结构清晰,分步骤说明,代码示例正确,并且相关问题覆盖用户可能进一步的需求,比如调试、多线程处理、参数转换等。需要参考之前的回答,但根据新的引用内容补充细节,确保信息全面准确。</think>### JMeter自定义函数开发教程(附完整示例代码) 根据Apache JMeter官方扩展规范和实际开发经验[^1][^2],开发自定义函数需重点关注以下核心要素: --- #### 一、开发规范要点 1. **包命名要求**:必须包含`functions`后缀,如:`com.yourcompany.functions` 2. **类继承关系**:需继承`AbstractFunction`抽象类 3. **方法实现要求**:必须重写`execute()`, `setParameters()`, `getReferenceKey()`, `getArgumentDesc()`四个核心方法 4. **线程安全**:函数需支持多线程并发调用(避免使用类成员变量) --- #### 二、完整开发流程(示例:生成范围随机数函数) **1. 创建Maven项目** ```xml <dependencies> <!-- 核心依赖 --> <dependency> <groupId>org.apache.jmeter</groupId> <artifactId>ApacheJMeter_core</artifactId> <version>5.6.2</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.jmeter</groupId> <artifactId>ApacheJMeter_functions</artifactId> <version>5.6.2</version> <scope>provided</scope> </dependency> </dependencies> ``` **2. 实现函数逻辑(RangeRandom.java)** ```java package com.loadtest.functions; import org.apache.jmeter.engine.util.CompoundVariable; import org.apache.jmeter.functions.AbstractFunction; import org.apache.jmeter.samplers.SampleResult; import org.apache.jmeter.samplers.Sampler; import java.util.*; public class RangeRandom extends AbstractFunction { private static final String KEY = "__RangeRandom"; private static final List<String> DESC = Arrays.asList("最小值", "最大值"); private CompoundVariable minVal, maxVal; @Override public String execute(SampleResult sampleResult, Sampler sampler) { int min = Integer.parseInt(minVal.execute()); int max = Integer.parseInt(maxVal.execute()); return String.valueOf(new Random().nextInt(max - min + 1) + min); } @Override public void setParameters(Collection<CompoundVariable> parameters) { checkParameterCount(parameters, 2); Iterator<CompoundVariable> it = parameters.iterator(); minVal = it.next(); maxVal = it.next(); } @Override public String getReferenceKey() { return KEY; } @Override public List<String> getArgumentDesc() { return DESC; } } ``` **3. 构建与部署** ```bash mvn clean package # 生成target/your-function.jar cp target/your-function.jar ${JMETER_HOME}/lib/ext/ ``` --- #### 三、验证与调用 1. **JMeter重启后**,通过函数助手调用: ``` ${__RangeRandom(100,200)} ``` 2. **调试验证**:使用Debug Sampler查看参数传递 ```java // 调试代码片段 log.info("Generated value: " + vars.get("YOUR_VAR")); ``` --- #### 四、最佳实践建议 1. **参数校验**:在`execute()`方法中添加数值范围验证 ```java if (min >= max) throw new IllegalArgumentException("最小值必须小于最大值"); ``` 2. **性能优化**:使用`ThreadLocal<Random>`替代直接new Random() 3. **异常处理**:捕获`NumberFormatException`并返回友好提示 --- #### 五、常见问题排查 | 现象 | 解决方案 | |-------|----------| | 函数未加载 | 检查JAR文件是否在`lib/ext`目录 | | 参数数量错误 | 确认`setParameters()`中的参数数量检查 | | 类型转换失败 | 使用`CompoundVariable.execute()`获取字符串值后再转换 | | 多线程冲突 | 避免在类成员变量中存储状态数据[^3] |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值