JMeter中JSON请求体字段移除与值修改问题求助
解决JSR223 PreProcessor处理参数化JSON时始终进入default分支的问题
问题背景
需要在JMeter中对JSON请求体做预处理:
- 移除值为
null的字段 - 将值为
"emptyString"的字段替换为空字符串
使用Module Controller调用参数化HTTP请求,请求体示例:
{ "seId": "${seId}", "usr": "${usr}", "transactionDetails": { "tType": ${ttionType}, "note": "${Test_Project}" }, "isOtp": true }
在JSR223 PreProcessor中编写了Groovy代码,但代码始终进入default分支,无法触发"emptyString"的替换逻辑。
原代码:
import com.fasterxml.jackson.databind.ObjectMapper // Get the request body as a string def requestBody = sampler.getArguments().getArgument(0).getValue() // Parse the request body JSON def objectMapper = new ObjectMapper() def json = objectMapper.readTree(requestBody) // Iterate over JSON fields json.fields().each { field -> // Check if field value is null and remove the field if (field.value.isNull()) { log.info("Removing field '${field.key}' because its value is null.") json.remove(field.key) } else { // Identify specific field values and take actions def value = field.value.textValue() switch (value) { case "emptyString": log.info("Replacing value of field '${field.key}' with empty string.") json.put(field.key, "") break // Add more cases as needed for other actions default: // Do nothing for other values log.info("No action taken for field '${field.key}' with value '${value}'.") break } } } // Set the modified and formatted request body def modifiedBody = json.toPrettyString() sampler.getArguments().getArgument(0).setValue(modifiedBody)
问题原因
- 变量替换时机错误:PreProcessor执行时,
${xxx}这类参数占位符还未被JMeter替换为实际值,此时解析JSON拿到的是占位符文本,而非预期的"emptyString"。 - 未处理嵌套结构:原代码仅遍历顶层JSON字段,像
transactionDetails这类嵌套对象里的字段完全被忽略。 - 类型判断不严谨:
textValue()仅对字符串类型节点有效,布尔/数字类型节点调用该方法会返回null,直接进入default分支。
修正后的代码
import com.fasterxml.jackson.databind.ObjectMapper import org.apache.jmeter.util.JMeterUtils // 先完成JMeter变量替换,获取真实请求体内容 def requestBody = JMeterUtils.replaceVariables(sampler.getArguments().getArgument(0).getValue()) // 解析JSON def objectMapper = new ObjectMapper() def json = objectMapper.readTree(requestBody) // 递归处理所有JSON节点(对象、数组) def processNode(def node) { if (node.isObject()) { // 使用迭代器避免并发修改异常 def iterator = node.fields() while (iterator.hasNext()) { def field = iterator.next() def key = field.key def value = field.value if (value.isNull()) { log.info("移除字段 '${key}',值为null") iterator.remove() } else if (value.isTextual()) { def textValue = value.textValue() if ("emptyString".equals(textValue)) { log.info("将字段 '${key}' 的值替换为空字符串") node.put(key, "") } } else if (value.isObject() || value.isArray()) { // 递归处理嵌套对象或数组 processNode(value) } } } else if (node.isArray()) { // 遍历数组元素并递归处理 node.forEach { element -> processNode(element) } } } // 启动处理逻辑 processNode(json) // 设置修改后的请求体 sampler.getArguments().getArgument(0).setValue(json.toPrettyString())
关键修正说明
- 提前完成变量替换:用
JMeterUtils.replaceVariables()先将所有占位符替换为实际参数值,确保解析的是真实请求内容。 - 递归处理嵌套结构:新增
processNode方法,遍历所有层级的JSON节点,不会遗漏深层字段。 - 安全遍历对象字段:使用迭代器遍历,解决直接修改JSON时的并发修改异常。
- 精准类型判断:先通过
isTextual()判断节点类型,再调用textValue(),避免非字符串节点返回null导致误判。
内容的提问来源于stack exchange,提问作者Ryooo
相关产品推荐
相关产品推荐

