
本文介绍在 jmeter 中使用 groovy 脚本动态解析未知结构的 json 响应,无需预定义字段即可完整提取所有路径式键名及其对应值,适用于接口自动化测试中灵活处理嵌套、数组、动态字段等复杂场景。
本文介绍在 jmeter 中使用 groovy 脚本动态解析未知结构的 json 响应,无需预定义字段即可完整提取所有路径式键名及其对应值,适用于接口自动化测试中灵活处理嵌套、数组、动态字段等复杂场景。
在 JMeter 性能测试中,常遇到 API 返回结构不固定或字段名动态生成的情况(例如设备列表中每个 device 的 attributes 字段包含不同子键)。此时无法使用标准的 JSON Extractor(需提前指定 JSON Path),而必须借助 JSR223 Sampler + Groovy 实现运行时全量键值遍历。
以下是一个增强版的递归遍历脚本,不仅能生成带层级路径的键名(如 devices[0].attributes.name),还能同时捕获其对应的原始值(支持字符串、数字、布尔、null 等类型),并将结果以 [key: value] 映射形式输出:
import groovy.json.JsonSlurper
def traverse = { tree, result = [], prefix = '' ->
switch (tree) {
case Map:
tree.each { k, v ->
def keyName = prefix ? "${prefix}.${k}" : k
if (v instanceof Map || v instanceof Collection) {
// 继续递归:对象或数组不直接存值,只记录路径
result << keyName
traverse(v, result, keyName)
} else {
// 叶子节点:存储完整键值对(保留原始类型)
result << [(keyName): v]
}
}
break
case Collection:
tree.eachWithIndex { item, idx ->
def arrayKey = "${prefix}[${idx}]"
if (item instanceof Map || item instanceof Collection) {
traverse(item, result, arrayKey)
} else {
result << [(arrayKey): item]
}
}
break
default:
// 基础类型(String/Number/Boolean/Null)直接作为叶子值
if (prefix) {
result << [(prefix): tree]
}
}
}
// 解析上一个请求的响应体
def response = prev.getResponseDataAsString()
if (response?.trim()) {
def json = new JsonSlurper().parseText(response)
def allEntries = []
traverse(json, allEntries)
// 打印所有键值对(调试用)
allEntries.each { entry ->
if (entry instanceof Map) {
entry.each { k, v ->
log.info("KEY: ${k} → VALUE: ${v.class.simpleName} = ${v}")
// 可选:将键值存入 JMeter 变量供后续使用
// vars.put("json_key_" + k.replaceAll(/[^a-zA-Z0-9_]/, '_'), v.toString())
}
} else {
log.info("PATH ONLY: ${entry}") // 如 "devices[0].attributes"(空对象/数组)
}
}
} else {
log.warn("Empty or null response received.")
}✅ 关键特性说明:
- ✅ 支持任意深度嵌套对象与数组(含混合结构);
- ✅ 自动构建带索引的路径名(如 items[0].details.tags[1]);
- ✅ 区分“容器路径”(纯结构路径)与“叶子键值对”,避免丢失语义;
- ✅ 保留原始数据类型(Integer、Boolean、null 不被转为字符串);
- ✅ 兼容 JMeter 5.0+ 与 Groovy 3+,无需额外依赖。
⚠️ 注意事项:
- 若需在后续 Sampler 中复用这些键值,建议用 vars.put("key_name", value.toString()) 存为 JMeter 变量(注意:JMeter 变量值始终为字符串);
- 对超大 JSON(>10MB),递归可能触发栈溢出,可改用基于 JsonParser 的迭代式解析(需手动维护栈);
- 生产环境建议添加 try/catch 包裹 parseText(),防止非法 JSON 导致线程中断;
- 路径中的特殊字符(.、[、])在用作变量名时需替换为下划线等安全字符。
通过该方案,你不再受限于 JSON Schema 的先验知识,真正实现“响应即契约”的动态测试能力——无论后端返回多少设备、多深嵌套、何种字段组合,都能一键提取全部有效载荷。

















