如何在JMeter中使用JSR223 PreProcessor提取PDF文本内容
前置准备
- 下载Apache PDFBox的二进制包,把包内的
pdfbox-xxx.jar、fontbox-xxx.jar、commons-logging-xxx.jar三个文件拷贝到JMeter安装目录的lib文件夹下,操作完成后重启JMeter,否则脚本运行时会报类找不到的错误。 - 提前确认待提取PDF的来源:本地静态文件直接拿绝对路径即可;如果是接口响应返回的PDF,可以先存为临时文件,或者直接读取响应字节流处理,不需要落盘。
JSR223预处理器配置流程
- 找到需要用到PDF提取内容的采样器,右键依次选择「添加-前置处理器-JSR223 预处理器」
- 预处理器面板的「语言」下拉项选择
groovy,注意:这是JSR223组件推荐使用的唯一语言,其余可选语言(如BeanShell)执行性能差、存在语法兼容问题,不建议使用,Groovy脚本会在首次运行时编译缓存,不会额外消耗压测性能。 - 将对应逻辑写入脚本输入框,参考可运行代码如下:
import org.apache.pdfbox.pdmodel.PDDocument import org.apache.pdfbox.text.PDFTextStripper import java.io.File // 替换为实际PDF路径,也可以通过vars.get()引用之前存的JMeter变量 String pdfFilePath = "D:/testdata/target.pdf" PDDocument document = null try { // 普通无密码PDF加载方式 document = PDDocument.load(new File(pdfFilePath)) // 加密PDF替换为下面的写法,传入打开密码 // document = PDDocument.load(new File(pdfFilePath), "pdf_open_password") PDFTextStripper textStripper = new PDFTextStripper() // 可选:指定提取页码范围,比如只提取2-5页 // textStripper.setStartPage(2) // textStripper.setEndPage(5) // 提取全量文本 String fullPdfText = textStripper.getText(document) // 将提取结果存入JMeter变量,后续组件可直接通过${pdf_full_text}引用 vars.put("pdf_full_text", fullPdfText) // 可直接在脚本中通过正则截取需要的特定字段,比如提取订单号 def orderNoMatch = (fullPdfText =~ /订单编号:([A-Z0-9]+)/) if (orderNoMatch.find()) { vars.put("pdf_order_no", orderNoMatch.group(1)) } // 日志打印前200字预览,方便调试 log.info("PDF提取完成,内容预览:{}", fullPdfText.take(200)) } catch (Exception e) { log.error("PDF文本提取失败", e) SampleResult.setSuccessful(false) SampleResult.setResponseMessage("PDF提取异常:" + e.getMessage()) } finally { // 必须关闭文档实例,避免文件句柄泄漏 if (document != null) { document.close() } }
常见问题处理
- 接口返回流直接处理:如果待提取PDF是上一个接口的响应内容,不需要存本地,直接读取响应字节流加载即可,替换加载逻辑为:
import java.io.ByteArrayInputStream byte[] pdfBytes = prev.getResponseData() document = PDDocument.load(new ByteArrayInputStream(pdfBytes))
- 乱码问题:如果提取出的内容全是乱码,先确认PDF是不是扫描生成的图片版PDF——这类PDF没有内嵌文本层,PDFBox无法直接提取内容,需要额外集成Tess4J等OCR组件做图像识别才能拿到文本;如果是可正常复制文本的PDF出现乱码,检查PDFBox版本是否过低,升级到最新稳定版即可解决。
- 性能优化:压测场景下尽量不要提取全量PDF文本,只通过正则、字符串截取拿需要的字段即可,减少不必要的内存占用和CPU消耗,避免影响压测结果准确性。
内容的提问来源于stack exchange,提问作者avidey
相关产品推荐
相关产品推荐

