JMeter中计算变量并作为请求头发送的方法(含HMAC场景)
一、BeanShell预处理程序变量未替换的解决步骤
你的代码出现变量未被替换的问题,可从以下几点逐一排查修复:
检查预处理程序位置:BeanShell预处理程序必须放在目标HTTP请求的子节点下,或确保其作用域覆盖到要使用变量的请求头管理器。如果请求头是全局配置,预处理程序要放在线程组最前面,保证请求发送前先执行脚本。
导入缺失工具类:代码中使用的
DateUtils属于Apache Commons Lang库,JMeter不会自动导入,需在脚本开头添加导入语句,否则脚本执行失败,变量无法设置:import org.apache.commons.lang3.time.DateUtils; Date timestamp = new Date(); String now = DateUtils.toIso8601Date(timestamp); vars.put("timestamp", now);可通过JMeter右上角的日志按钮(黄色感叹号)查看是否有类找不到的报错。
验证变量生成状态:添加
Debug Sampler,勾选「JMeter Variables」选项,运行后查看结果树中的Debug输出,确认timestamp变量是否存在且值正确。替换为JSR223预处理程序(推荐):BeanShell性能较差,JMeter官方推荐使用JSR223预处理程序搭配Groovy语言,语法更简洁且自动导入常用类。生成ISO8601时间戳的Groovy代码如下:
import java.time.OffsetDateTime import java.time.format.DateTimeFormatter def isoTimestamp = OffsetDateTime.now().format(DateTimeFormatter.ISO_OFFSET_DATE_TIME) vars.put("timestamp", isoTimestamp)
二、HMAC签名的实现方法
JMeter的预处理程序机制和Postman前置脚本完全对应,用JSR223预处理程序(Groovy)可轻松实现HMAC签名计算,步骤如下:
准备签名参数:确定签名需要的内容(比如时间戳、请求体、固定字符串等),将这些内容存入JMeter变量(比如前面生成的
timestamp)。编写Groovy签名脚本:以HMAC-SHA256为例,代码如下:
import javax.crypto.Mac import javax.crypto.spec.SecretKeySpec import java.util.Base64 // 替换为你的实际密钥 def secretKey = "your-api-secret" // 按接口要求的规则拼接待签名内容 def signContent = vars.get("timestamp") + vars.get("requestBody") // 初始化HMAC算法 Mac mac = Mac.getInstance("HmacSHA256") SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA256") mac.init(keySpec) // 计算签名并转为Base64格式(如需十六进制,替换为signatureBytes.encodeHex().toString()) byte[] signBytes = mac.doFinal(signContent.getBytes("UTF-8")) def hmacSign = Base64.getEncoder().encodeToString(signBytes) // 将签名存入变量,供请求头使用 vars.put("hmacSignature", hmacSign)注:如果需要获取请求体内容,可用
prev.getSampler().getArguments().getArgument(0).getValue()获取当前HTTP请求的请求体,提前存入变量。在请求头中引用签名变量:在请求头管理器中添加对应的头字段,比如:
Authorization: HMAC ${hmacSignature}按接口要求的格式调整即可。
内容的提问来源于stack exchange,提问作者carlos palma

