You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JMeter中JSON请求体字段移除与值修改问题求助

解决JSR223 PreProcessor处理参数化JSON时始终进入default分支的问题

问题背景

需要在JMeter中对JSON请求体做预处理:

  1. 移除值为null的字段
  2. 将值为"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)

问题原因

  1. 变量替换时机错误:PreProcessor执行时,${xxx}这类参数占位符还未被JMeter替换为实际值,此时解析JSON拿到的是占位符文本,而非预期的"emptyString"。
  2. 未处理嵌套结构:原代码仅遍历顶层JSON字段,像transactionDetails这类嵌套对象里的字段完全被忽略。
  3. 类型判断不严谨: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 21:13:22