如何使用JMeter将PDF内容存入变量并上传为multipart/related API请求
一、读取PDF文件内容到JMeter变量
使用JSR223元件(推荐Groovy脚本,性能优于BeanShell)完成文件读取,支持直接存储字节数组或Base64编码字符串:
- 在目标HTTP请求前添加JSR223 PreProcessor
- 选择Groovy作为脚本语言,写入以下代码:
方式1:存储原始字节数组(适合二进制上传场景)
// 替换为你的PDF文件绝对路径 def pdfFilePath = "/Users/test/docs/sample.pdf" def pdfFile = new File(pdfFilePath) byte[] pdfBytes = pdfFile.bytes // 将字节数组存入JMeter变量,命名为pdfContent vars.putObject("pdfContent", pdfBytes)
方式2:存储Base64编码字符串(适合要求文本传输的API)
def pdfFilePath = "/Users/test/docs/sample.pdf" def pdfFile = new File(pdfFilePath) byte[] pdfBytes = pdfFile.bytes String base64Pdf = new String(Base64.getEncoder().encode(pdfBytes)) // 存入字符串变量 vars.put("pdfContentBase64", base64Pdf)
二、构造multipart/related类型的HTTP请求
multipart/related请求需要指定边界符(boundary),并按格式拆分请求体各部分:
步骤1:配置请求头
添加HTTP Header Manager,设置以下请求头:
Content-Type:multipart/related; boundary=JMeter-Custom-Boundary-123(替换为自定义的边界符,避免与内容冲突)
步骤2:编写请求体
根据API要求,在HTTP请求的「Body Data」中按multipart格式编写,引用之前的变量:
示例(混合元数据与PDF内容)
--JMeter-Custom-Boundary-123 Content-Type: application/json Content-Disposition: form-data; name="metadata" {"fileName": "sample.pdf", "documentType": "invoice"} --JMeter-Custom-Boundary-123 Content-Type: application/pdf Content-Disposition: form-data; name="file"; filename="sample.pdf" ${__BeanShell(new String(vars.getObject("pdfContent"), "ISO-8859-1"))} --JMeter-Custom-Boundary-123--
说明:
- 每部分用边界符分隔,最后一个边界符需加
--结尾 - 使用
__BeanShell函数将字节数组转成字符串(ISO-8859-1编码可保证二进制内容不损坏) - 若使用Base64变量,直接替换为
${pdfContentBase64}即可
可选:动态生成请求体
如果需要更灵活的构造逻辑,可在JSR223 PreProcessor中生成完整请求体:
def boundary = "JMeter-Custom-Boundary-123" def metadata = '{"fileName": "sample.pdf"}' def pdfBytes = vars.getObject("pdfContent") def bodyBuilder = new StringBuilder() // 添加元数据部分 bodyBuilder.append("--").append(boundary).append("\r\n") bodyBuilder.append("Content-Type: application/json\r\n") bodyBuilder.append("Content-Disposition: form-data; name=\"metadata\"\r\n\r\n") bodyBuilder.append(metadata).append("\r\n") // 添加PDF部分 bodyBuilder.append("--").append(boundary).append("\r\n") bodyBuilder.append("Content-Type: application/pdf\r\n") bodyBuilder.append("Content-Disposition: form-data; name=\"file\"; filename=\"sample.pdf\"\r\n\r\n") bodyBuilder.append(new String(pdfBytes, "ISO-8859-1")).append("\r\n") // 结尾边界符 bodyBuilder.append("--").append(boundary).append("--\r\n") // 存入变量供HTTP请求使用 vars.put("multipartRequestBody", bodyBuilder.toString())
之后在HTTP请求的「Body Data」中直接引用${multipartRequestBody}即可。
注意事项
- 确保JMeter有PDF文件的读取权限,路径尽量使用绝对路径
- 边界符不要与请求体中的任何内容重复,建议使用随机字符串
- 若API要求
Content-Type包含start参数(指定起始部分),需补充为multipart/related; boundary=xxx; start=metadata - 用「View Results Tree」查看请求体格式,对比正常API请求的结构是否一致
内容的提问来源于stack exchange,提问作者Pratik Dey
相关产品推荐
相关产品推荐

