JMeter如何实现POST请求Payload参数化及Base64编码(对接Google Pub/Sub)
实现JMeter向Google Pub/Sub发送参数化Payload的落地方案
核心调整思路
原方案将完整明文JSON存入CSV,无法对内部字段单独做动态化(比如批量替换某字段测试值、动态生成时间戳等)。调整后不再将整段JSON作为CSV字段,而是拆分需要动态化的字段为独立CSV列,发送前临时拼接完整JSON再做Base64编码,兼顾参数灵活性和接口格式要求。
具体实现步骤
1. 调整CSV配置与测试数据格式
- 改用CSV Data Set Config拆分字段,不再存储整段JSON
- 示例CSV表头(可根据需要增减动态字段):
identId,requestId,requestid,timeStamp,version,eventId,creatorId,messageTTL,checkid,troubleSource,diagData - 对应测试数据行示例:
123456,,1,1617873956,0.0.0.1,1,0,34560,1,0,"[2020-01-01 16:00:53.707961][[lat[0]][long[0]][alt[0]][canbetrust[0]][mars[0]]][signal[5]][TEM2 wake up]" - CSV Data Set Config需开启
允许带引号数据选项,适配包含特殊字符的字段。
2. 修改前置编码脚本
按需选择以下两种实现方案:
场景1:保留原有BeanShell PreProcessor
直接替换原有脚本逻辑,先拼接完整JSON再编码:
import org.apache.jmeter.protocol.http.util.Base64Encoder; // 从变量获取拆分后的参数 String identId = vars.get("identId"); String requestId = vars.get("requestId"); String requestid = vars.get("requestid"); String timeStamp = vars.get("timeStamp"); String version = vars.get("version"); String eventId = vars.get("eventId"); String creatorId = vars.get("creatorId"); String messageTTL = vars.get("messageTTL"); String checkid = vars.get("checkid"); String troubleSource = vars.get("troubleSource"); String diagData = vars.get("diagData"); // 处理空requestId为JSON原生null String requestIdJson = (requestId != null && !requestId.isEmpty()) ? "\"" + requestId + "\"" : "null"; // 拼接完整明文JSON,注意字符串类型加双引号,数字不加,特殊字符转义 String rawPayload = "{" + "\"identId\":\"" + identId + "\"," + "\"requestId\":" + requestIdJson + "," + "\"payload\":{" + "\"header\":{" + "\"requestid\":" + requestid + "," + "\"timeStamp\":" + timeStamp + "," + "\"version\":\"" + version + "\"," + "\"eventId\":" + eventId + "," + "\"creatorId\":" + creatorId + "," + "\"messageTTL\":" + messageTTL + "}," + "\"body\":{" + "\"checkid\":" + checkid + "," + "\"checkData\":{" + "\"diagnosticsData\":{" + "\"troubleSource\":" + troubleSource + "," + "\"data\":\"" + diagData.replace("\"", "\\\"") + "\"" + "}" + "}" + "}" + "}" + "}"; // 编码Base64并存入变量 String encodedPayload = Base64Encoder.encode(rawPayload); vars.put("csv_payload_encoded", encodedPayload);
场景2:推荐使用JSR223 PreProcessor(Groovy)
压测场景下Groovy性能远优于BeanShell,且自带JSON序列化能力,避免手动拼接的转义错误:
import org.apache.jmeter.protocol.http.util.Base64Encoder import groovy.json.JsonOutput // 组装参数Map,自动处理类型适配 def params = [ identId: vars.get("identId"), requestId: vars.get("requestId") ?: null, payload: [ header: [ requestid: vars.get("requestid") as int, timeStamp: vars.get("timeStamp") as long, version: vars.get("version"), eventId: vars.get("eventId") as int, creatorId: vars.get("creatorId") as int, messageTTL: vars.get("messageTTL") as int ], body: [ checkid: vars.get("checkid") as int, checkData: [ diagnosticsData: [ troubleSource: vars.get("troubleSource") as int, data: vars.get("diagData") ] ] ] ] ] // 自动生成合规JSON,无需手动转义 def rawPayload = JsonOutput.toJson(params) def encodedPayload = Base64Encoder.encode(rawPayload) vars.put("csv_payload_encoded", encodedPayload)
3. POST请求无需调整
原有Pub/Sub接口的请求体保持不变,仍使用${csv_payload_encoded}引用编码后的变量即可,符合接口格式要求。
注意事项
- 手动拼接JSON时需严格区分字符串、数字、null的格式,避免遗漏双引号或类型错误
- 若字段包含双引号、反斜杠等特殊字符,需手动转义,或直接使用Groovy方案规避该问题
- 压测场景优先选择JSR223 Groovy方案,减少性能损耗
内容的提问来源于stack exchange,提问作者Martin Jönsson
相关产品推荐
相关产品推荐

