JMeter自定义HTTP组件

JMeter是一个优秀的开源项目 , 我们可以在jmeter的官网了解到如何使用和如何二次开发:https://jmeter.apache.org/
因工作需要,最近做了一个JMeter自定义的http组件(其实就是在http的基础上加了点东西而已) 。现就该需求为例,简要地分享如何实现jmeter自定义组件 。
1、了解jmeter架构我们先按照平常使用jmeter的思路 , 看看jmeter到底保存了什么东西?

JMeter自定义HTTP组件

文章插图
JMeter自定义HTTP组件

文章插图
可以看到 , 每一个组件都有一个guiclass和testclass 。guiclass就是你能看到的页面的代码,testclass就是你点击运行时后台处理的代码 。
Jmeter由多个模块组成,其中我们本次需要了解的是http模块 。我们常用的“http请求”取样器就是以HttpTestSampleGui+HTTPSamplerProxy(HTTPSamplerProxy为final类,故需继承其父类HTTPSamplerBase)组成 。
JMeter自定义HTTP组件

文章插图
注:图片描述不是完全准确,仅就所需内容铺排 , 大致了解即可 。后续图片亦然 。
2、需求分析一般我们请求接口,需要在请求头上添加token等签名 。而我本次需求,是在调用系统接口前,需要添加签名到请求体,而这个签名是使用系统门户生成的key和access、时间戳、请求体等,通过某种算法生成的 。
系统生成签名分为两个情况:
JMeter自定义HTTP组件

文章插图
1、发起获取session请求时,使用key、access、timestamp生成签名 。(获取session在单线程组中只需要调用一次)
2、发起其他请求时,使用第一步获取到的session、key、access、timestamp、请求体生成签名 。(其他请求可能调用多次)
那么对于这个需求 , 我一开始的处理方法是:在“http请求”下,添加“前置处理器”,生成签名 。针对获取session的请求还需要再添加“json提取器”提取session 。
但这么做发现我们新增的每一个请求都要添加“前置处理器” , 实现同样的逻辑代码 。我们能不能提供一个新的组件,让用户在不改变原http请求的逻辑上,自动生成签名呢?
我们可以在“http请求”的基础上 , 通过继承原生的HttpTestSampleGui和HTTPSamplerBase来实现自定义组件!
JMeter自定义HTTP组件

文章插图
针对这个需求,我认为我们应该自定义两个组件,分别处理获取session请求和其他请求 。用户在线程组里填入key、access,只需新增一个“PaimonSession请求” , 请求后自动把接口返回的session存到这个线程组的公共变量里(即jmeter的vars变量) 。对于其他请求,用户可以新增多个“Paimon请求”,填写的内容与普通http请求一致 。
这里会引起另一个问题 , 就是如何配置key、access?一开始我们使用“用户定义的变量”配置 , 但发现多个线程组的情况下,会出现后者覆盖前者的情况,即无法做到每个线程组拥有独立的key、access 。所以能否在原生的http请求上添加两个输入框呢?
原生:
JMeter自定义HTTP组件

文章插图
预期:
JMeter自定义HTTP组件

文章插图
需求转化:自定义两个组件 , 两个组件都需要在发起请求前生成签名并添加到请求头 , 其中一个组件需要新增两个输入框 。
3、源码分析3.1、需求一:增加输入框我们根据jmx文件,分析源码 。以contentEncoding为例,我们下载jmeter对应版本的源码,查看HttpTestSampleGui文件,在HttpTestSampleGui找不到contentEncoding这个变量 。熟悉前端的同学可能会想到 , 前端一般会使用组件的形式达到代码复用的效果 。这里jmeter也是这样实现的,guiclass是组件嵌套的 。通过查看源码 , 可以在HttpTestSampleGui找到UrlConfigGui,UrlConfigGui内出现了contentEncoding这个变量(其实在查找原生组件的时候,我一般是调试jmeter源码)
JMeter自定义HTTP组件

文章插图

JMeter自定义HTTP组件

文章插图
JMeter自定义HTTP组件

文章插图
所以除了继承HttpTestSampleGui和HTTPSamplerBase,我们还需要继承UrlConfigGui 。
JMeter自定义HTTP组件

推荐阅读