├── .gitignore
├── README.md
├── assembly.xml
├── beanshell
├── README.md
├── assert.bsh
└── sql.bsh
├── common-util
├── README.md
├── pom.xml
└── src
│ └── main
│ └── java
│ └── org
│ └── apache
│ └── jmeter
│ ├── common
│ ├── cli
│ │ └── CliOptions.java
│ ├── encryption
│ │ └── Signature.java
│ ├── exceptions
│ │ ├── JBDCException.java
│ │ └── ServiceException.java
│ ├── google
│ │ └── GoogleAuthenticator.java
│ ├── jmeter
│ │ ├── JMeterGuiUtil.java
│ │ ├── JMeterVariablesUtil.java
│ │ └── ValueReplaceUtil.java
│ ├── json
│ │ ├── DoubleTypeAdapter.java
│ │ ├── JsonFileUtil.java
│ │ ├── JsonPathUtil.java
│ │ ├── JsonUtil.java
│ │ └── MapTypeAdapter.java
│ ├── office
│ │ └── ExcelUtil.java
│ ├── random
│ │ ├── AreaCode.java
│ │ ├── CambodiaMobilePhone.java
│ │ ├── IDCard.java
│ │ ├── MobilePhone.java
│ │ └── Randoms.java
│ ├── redis
│ │ ├── Redis.java
│ │ └── RedisCluster.java
│ ├── ssh
│ │ ├── GoogleAuthUserInfo.java
│ │ ├── SSHTelnetClient.java
│ │ └── SSHUtil.java
│ ├── telnet
│ │ └── TelnetUtil.java
│ └── utils
│ │ ├── DesktopUtil.java
│ │ ├── ExceptionUtil.java
│ │ ├── FileUtil.java
│ │ ├── JsonConfigUtil.java
│ │ ├── NetworkUtil.java
│ │ ├── PathUtil.java
│ │ ├── ReflectUtil.java
│ │ ├── RuntimeUtil.java
│ │ ├── StringUtil.java
│ │ ├── TimeUtil.java
│ │ └── YamlUtil.java
│ └── engine
│ └── util
│ ├── SimpleValueReplacer.java
│ └── SimpleVariableNoContext.java
├── configs
├── README.md
├── pom.xml
└── src
│ └── main
│ └── java
│ └── org
│ └── apache
│ └── jmeter
│ └── config
│ ├── EnvDataSet.java
│ ├── FailureResultSaver.java
│ ├── HTTPHeaderReader.java
│ ├── SSHConfiguration.java
│ ├── ScriptArgumentsDescriptor.java
│ ├── TraversalDataSet.java
│ ├── TraversalEmptyValue.java
│ └── gui
│ ├── EnvDataSetGui.java
│ ├── FailureResultSaverGui.java
│ ├── HTTPHeaderReaderGui.java
│ ├── SSHConfigurationGui.java
│ ├── ScriptArgumentsDescriptorGui.java
│ ├── TraversalDataSetGui.java
│ └── TraversalEmptyValueGui.java
├── docs
├── JMeter+Jenkins+Python接口自动化方案.excalidraw
├── images
│ ├── DubboTelnetSampler_001.png
│ ├── EnvDataSet_001.png
│ ├── FailureResultSaver_001.png
│ ├── HTTPHeaderReader_001.png
│ ├── JMeterScriptSampler_001.png
│ ├── JMeter_Jenkins_Python_Interface_Automation_Testplan.png
│ ├── LocalHtmlReport_001.png
│ ├── LocalHtmlReport_002.png
│ ├── LocalHtmlReport_003.png
│ ├── LocalHtmlReport_004.png
│ ├── SSHConfiguration_001.png
│ ├── TraversalDataSet_001.png
│ ├── TraversalDataSet_002.png
│ ├── TraversalDataSet_003.png
│ ├── TraversalEmptyValue_001.png
│ ├── TraversalEmptyValue_002.png
│ └── TraversalEmptyValue_003.png
└── 常用函数.md
├── functions
├── README.md
├── pom.xml
└── src
│ └── main
│ └── java
│ └── org
│ └── apache
│ └── jmeter
│ └── functions
│ ├── ExtractPrevResponse.java
│ ├── ExtractSQLValue.java
│ ├── GoogleAuth.java
│ ├── JmeterHome.java
│ ├── MD5.java
│ ├── RCambodiaMobile.java
│ ├── RIdCard.java
│ ├── RMobile.java
│ ├── RNumber.java
│ └── ScriptAbsPath.java
├── infautomator
└── pom.xml
├── pom.xml
├── samplers
├── README.md
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── org
│ │ └── apache
│ │ └── jmeter
│ │ └── samplers
│ │ ├── DubboTelnetSampler.java
│ │ ├── JMeterScriptDataForwarder.java
│ │ ├── JMeterScriptSampler.java
│ │ └── gui
│ │ ├── DubboTelnetSamplerGui.java
│ │ └── JMeterScriptSamplerGui.java
│ └── resources
│ └── log4j2.xml
└── visualizers
├── README.md
├── pom.xml
└── src
└── main
├── java
└── org
│ └── apache
│ └── jmeter
│ └── visualizers
│ ├── ReportCollector.java
│ ├── ReportManager.java
│ ├── gui
│ └── LocalHtmlReportGui.java
│ ├── utils
│ ├── FreemarkerUtil.java
│ ├── JavaScriptUtil.java
│ └── JsoupUtil.java
│ └── vo
│ ├── OverviewInfoVO.java
│ ├── ReportInfoVO.java
│ ├── TestCaseVO.java
│ ├── TestDataSet.java
│ ├── TestStepVO.java
│ └── TestSuiteVO.java
└── resources
└── org
└── apache
└── jmeter
└── visualizers
└── utils
└── template
└── report.ftl
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Java template
3 | # Compiled class file
4 | *.class
5 |
6 | # Log file
7 | *.log
8 |
9 | # BlueJ files
10 | *.ctxt
11 |
12 | # Mobile Tools for Java (J2ME)
13 | .mtj.tmp/
14 |
15 | # Package Files #
16 | *.jar
17 | *.war
18 | *.ear
19 | *.zip
20 | *.tar.gz
21 | *.rar
22 |
23 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
24 | hs_err_pid*
25 |
26 | .idea/
27 | *.iml
28 | target/
29 |
30 | **/dependency-reduced-pom.xml
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # jmeter-plugins
2 | ## 一、项目介绍
3 | 一些自用的JMeter插件,可提高脚本的可维护性,可复用性,可读性和编写效率。
4 | 下图是JMeter + Jenkins + Python的接口自动化测试方案。
5 | 
6 |
7 | ## 二、打包和安装
8 | 1. 编译打包:`mvn clean assembly:assembly`。
9 | 2. 将编译好的jar包放至 `jmeterHome/lib/ext`目录下。
10 |
11 | ## 三、JMeter版本说明
12 | 所有插件均在JMeter-5.1.1版本上开发,理论上5.x版本均可正常使用,如使用过程中出现问题请使用5.1.1版本或联系我
13 |
14 | ## 四、插件介绍
15 | ### Configs [→](https://github.com/YeKelvin/jmeter-plugins/tree/master/configs)
16 | - **环境变量配置器(EnvDataSet):** 根据`.yaml`配置文件加载测试环境变量,脚本中通过`${keyName}`占位符引用
17 | - **失败请求保存器(FailureResultSaver):** 用于性能测试时,把失败的请求数据单独保存下来,方便定位问题
18 | - **HTTP请求头读取器(HTTPHeaderReader):** HTTP信息头管理器的文件版,根据`.yaml`配置文件加载请求头
19 | - **SSH配置器(SSHConfiguration):** 配置ssh,多用于内网跳板机端口转发,目的是本地直连跳板机后的内部服务
20 | - **数据遍历配置器(TraversalDataSet):** 用于枚举遍历测试,完成遍历后线程自动停止线程
21 | - **空值遍历配置器(TraversalEmptyValue):** 用于遍历报文字段做非空校验,完成遍历后线程自动停止线程
22 |
23 | ### Samplers [→](https://github.com/YeKelvin/jmeter-plugins/tree/master/samplers)
24 | - **DubboTelnet取样器(DubboTelnetSampler):** Dubbo接口插件,通过Telnet方式调用Dubbo接口
25 | - **JMeterScript取样器(JMeterScriptSampler):** 可在当前脚本中执行指定位置的JMeter脚本并获取执行结果,当前脚本和目标脚本可传递变量,该插件是提高脚本复用性的大杀器
26 |
27 | ### Visualizers [→](https://github.com/YeKelvin/jmeter-plugins/tree/master/visualizers)
28 | - **HTML报告(LocalHtmlReport):** 收集所有sampler数据保存至html文件中
29 |
30 | ### Functions [→](https://github.com/YeKelvin/jmeter-plugins/tree/master/functions)
31 | - **{__ExtractPrevResponse()}:** 根据JsonPath表达式提取上一个SamplerResponse的Json值
32 | - **{__ExtractSQLValue()}:** 根据列名提取数据库表第一行的值
33 | - **{__GoogleAuth()}:** 谷歌动态认证码
34 | - **{__JmeterHome()}:** 获取JMeter根目录的绝对路径
35 | - **{__MD5()}:** MD5加密
36 | - **{__RIdCard()}:** 随机生成国内身份证号
37 | - **{__RMobile()}:** 随机生成国内手机号
38 | - **{__RNumber()}:** 随机生成数字
39 | - **{__ScriptAbsPath()}:** 获取JMeter脚本所在目录的绝对路径
40 |
41 | ### common-util [→](https://github.com/YeKelvin/jmeter-plugins/tree/master/common-util)
42 | - 平时写脚本时常用的方法
43 |
44 | ### beanshell [→](https://github.com/YeKelvin/jmeter-plugins/tree/master/beanshell)
45 | - 平时写脚本时常用的bsh脚本
46 | - **assert.bsh:** 常用断言方法
47 | - **sql.bsh:** 对获取数据库表结果的方法封装
48 |
--------------------------------------------------------------------------------
/assembly.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 | jar
6 |
7 |
8 | dir
9 |
10 |
11 | false
12 |
13 |
14 |
15 | ${basedir}/infautomator/target
16 |
17 | jmeter-plugins-*.jar
18 |
19 | /
20 |
21 |
22 |
--------------------------------------------------------------------------------
/beanshell/README.md:
--------------------------------------------------------------------------------
1 | # BeanShell
2 | ## beanshell脚本依赖bsh脚本的方法
3 | ```java
4 | // bsh路径:xx/jmeterHome/beanshell/xxx.bsh
5 |
6 | source("${__JmeterHome(beanshell, assert.bsh)}");
7 | source("${__JmeterHome(beanshell, sql.bsh)}");
8 | ```
9 |
10 |
11 | ## assert.bsh
12 | - 常用断言方法
13 | ```java
14 | source("${__JmeterHome(beanshell, assert.bsh)}");
15 |
16 | assertSQLResultSize("TABLE_NAME", 1);
17 | assertEquals(source, expection);
18 | assertNotEquals(source, expection);
19 | assertTrue(boolean);
20 | assertFalse(boolean);
21 | assertNotNull(source);
22 | assertNull(source);
23 |
24 | String errorMsg = "测试失败了";
25 | assertSQLResultSize("TABLE_NAME", 1, errorMsg);
26 | assertEquals(source, expection, errorMsg);
27 | assertNotEquals(source, expection, errorMsg);
28 | assertTrue(boolean, errorMsg);
29 | assertFalse(boolean, errorMsg);
30 | assertNotNull(source, errorMsg);
31 | assertNull(source, errorMsg);
32 | ```
33 |
34 |
35 | ## sql.bsh
36 | - 对获取数据库表结果的方法封装
37 | ```java
38 | source("${__JmeterHome(beanshell, sql.bsh)}");
39 |
40 | String value = getTableValue("tableName", "columnName");
41 | String valueWithQuotes = getTableValue("tableName", "columnName", "defualtValue", true);
42 | String count = getTableCount("tableName");
43 | ```
44 |
45 |
46 | ## beanshell调试技巧
47 | - 有时beanshell报错信息就只有一条异常,完全不知道哪里出错了,可以把脚本内容套一层try-catch ,能输出更多异常堆栈信息
48 | ```java
49 | try {
50 | // 脚本内容写这里
51 | }catch (Throwable ex) {
52 | log.error("", ex);
53 | }
54 | ```
55 |
56 | ## bsh脚本source依赖
57 | ```java
58 | import org.apache.jmeter.util.JMeterUtils;
59 | import java.io.File;
60 |
61 | String bshHome = JMeterUtils.getJMeterHome() + File.separator + "beanshell";
62 | source(bshHome + File.separator + "xxx.bsh");
63 | ```
--------------------------------------------------------------------------------
/beanshell/assert.bsh:
--------------------------------------------------------------------------------
1 | import org.apache.commons.lang3.StringUtils;
2 |
3 |
4 | /**
5 | * 根据判断条件,condition=true时,停止当前 sample,输出错误信息(不知道为啥中文乱码,暂时用英文提示)
6 | */
7 | void stopThreadWithCondition(boolean condition, String testResult, String expectionResult) {
8 | if( condition ) {
9 | Failure = true;
10 | FailureMessage = "Test failed!! TestResult=" + testResult + ", ExpectionResult=" + expectionResult;
11 | Response.setStopThread(true);
12 | }
13 | }
14 |
15 | /**
16 | * 根据判断条件,condition=true时,停止当前 sample,输出自定义错误信息
17 | */
18 | void stopThreadWithCondition(boolean condition, String errorMsg) {
19 | if( condition ) {
20 | Failure = true;
21 | FailureMessage = errorMsg;
22 | Response.setStopThread(true);
23 | }
24 | }
25 |
26 | /**
27 | * 断言 SQL结果数
28 | */
29 | void assertSQLResultsSize(String tableName, int resultsSize) {
30 | Object tableObj = vars.getObject(tableName);
31 | // 判断JDBC Request中是否有正确设置表结果变量
32 | if(tableObj != null) {
33 | int tableResultSize = tableObj.size();
34 | String testResult = String.valueOf(tableResultSize);
35 | String expectionResult = String.valueOf(resultsSize);
36 | stopThreadWithCondition(tableResultSize != resultsSize, testResult, expectionResult);
37 | }else {
38 | String errorMsg = "tableName variable does not exist.";
39 | log.info(errorMsg);
40 | stopThreadWithCondition(true, errorMsg);
41 | }
42 | }
43 |
44 | /**
45 | * 断言 SQL结果数,带自定义错误信息
46 | */
47 | void assertSQLResultsSize(String tableName, int resultsSize, String errorMsg) {
48 | Object tableObj = vars.getObject(tableName);
49 | // 判断JDBC Request中是否有正确设置表结果变量
50 | if(tableObj != null) {
51 | int tableResultSize = tableObj.size();
52 | String testResult = String.valueOf(tableResultSize);
53 | String expectionResult = String.valueOf(resultsSize);
54 | stopThreadWithCondition(tableResultSize != resultsSize, errorMsg);
55 | }else {
56 | String errorMsg = "tableName variable does not exist.";
57 | log.info(errorMsg);
58 | stopThreadWithCondition(true, errorMsg);
59 | }
60 | }
61 |
62 | /**
63 | * 断言 String是否相等
64 | */
65 | void assertEquals(String source, String expection) {
66 | stopThreadWithCondition(!source.equals(expection), source, expection);
67 | }
68 |
69 | /**
70 | * 断言 String是否相等,带自定义错误信息
71 | */
72 | void assertEquals(String source, String expection, String errorMsg) {
73 | stopThreadWithCondition(!source.equals(expection), errorMsg);
74 | }
75 |
76 | /**
77 | * 断言 int是否相等
78 | */
79 | void assertEquals(int source, int expection) {
80 | stopThreadWithCondition(!(source==expection),
81 | String.valueOf(source),
82 | String.valueOf(expection));
83 | }
84 |
85 | /**
86 | * 断言 int是否相等,带自定义错误信息
87 | */
88 | void assertEquals(int source, int expection, String errorMsg) {
89 | stopThreadWithCondition(!(source==expection), errorMsg);
90 | }
91 |
92 | /**
93 | * 断言 float是否相等
94 | */
95 | void assertEquals(float source, float expection) {
96 | stopThreadWithCondition(!(source==expection),
97 | String.valueOf(source),
98 | String.valueOf(expection));
99 | }
100 |
101 | /**
102 | * 断言 float是否相等,带自定义错误信息
103 | */
104 | void assertEquals(float source, float expection, String errorMsg) {
105 | stopThreadWithCondition(!(source==expection), errorMsg);
106 | }
107 |
108 | /**
109 | * 断言 String是否不相等
110 | */
111 | void assertNotEquals(String source, String expection) {
112 | stopThreadWithCondition(source.equals(expection), source, expection);
113 | }
114 |
115 | /**
116 | * 断言 String是否不相等,带自定义错误信息
117 | */
118 | void assertNotEquals(String source, String expection, String errorMsg) {
119 | stopThreadWithCondition(source.equals(expection), errorMsg);
120 | }
121 |
122 | /**
123 | * 断言 int是否不相等
124 | */
125 | void assertNotEquals(int source, int expection) {
126 | stopThreadWithCondition((source==expection),
127 | String.valueOf(source),
128 | String.valueOf(expection));
129 | }
130 |
131 | /**
132 | * 断言 int是否不相等,带自定义错误信息
133 | */
134 | void assertNotEquals(int source, int expection, String errorMsg) {
135 | stopThreadWithCondition((source==expection), errorMsg);
136 | }
137 |
138 | /**
139 | * 断言 float是否不相等
140 | */
141 | void assertNotEquals(float source, float expection) {
142 | stopThreadWithCondition((source==expection),
143 | String.valueOf(source),
144 | String.valueOf(expection));
145 | }
146 |
147 | /**
148 | * 断言 float是否不相等,带自定义错误信息
149 | */
150 | void assertNotEquals(float source, float expection, String errorMsg) {
151 | stopThreadWithCondition((source==expection), errorMsg);
152 | }
153 |
154 | /**
155 | * 断言是否为 true
156 | */
157 | void assertTrue(boolean source) {
158 | stopThreadWithCondition(!(source && true), String.valueOf(source), "true");
159 | }
160 |
161 | /**
162 | * 断言是否为 false
163 | */
164 | void assertFalse(boolean source) {
165 | stopThreadWithCondition(!(!source && true), String.valueOf(source), "false");
166 | }
167 |
168 | /**
169 | * 断言是否为 true,带自定义错误信息
170 | */
171 | void assertTrue(boolean source, String errorMsg) {
172 | stopThreadWithCondition(!(source && true), errorMsg);
173 | }
174 |
175 | /**
176 | * 断言是否为 false,带自定义错误信息
177 | */
178 | void assertFalse(boolean source, String errorMsg) {
179 | stopThreadWithCondition(!(!source && true), errorMsg);
180 | }
181 |
182 | /**
183 | * 断言 String是否非 null
184 | */
185 | void assertNotNull(String source) {
186 | String sourceStr = source == null ? "null" : source;
187 | stopThreadWithCondition((source == null), sourceStr, "null");
188 | }
189 |
190 | /**
191 | * 断言 String是否非 null,带自定义错误信息
192 | */
193 | void assertNotNull(String source, String errorMsg) {
194 | stopThreadWithCondition((source == null), errorMsg);
195 | }
196 |
197 | /**
198 | * 断言 String是否为 null
199 | */
200 | void assertNull(String source) {
201 | String sourceStr = source == null ? "null" : source;
202 | stopThreadWithCondition((source != null), sourceStr, "not null");
203 | }
204 |
205 | /**
206 | * 断言 String是否为 null,带自定义错误信息
207 | */
208 | void assertNull(String source, String errorMsg) {
209 | stopThreadWithCondition((source != null), errorMsg);
210 | }
211 |
212 |
--------------------------------------------------------------------------------
/beanshell/sql.bsh:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * 获取String类型的SQL值
4 | */
5 | String getTableValue(String tableName, String columnName) {
6 | return String.valueOf(vars.getObject(tableName).get(0).get(columnName));
7 | }
8 |
9 | /**
10 | * 获取String类型的SQL值,如null则赋默认值defaultValue,withQuotes为true时,columnValue带双引号返回
11 | */
12 | String getTableValue(String tableName, String columnName, String defaultValue, boolean withQuotes) {
13 | String columnValue = vars.getObject(tableName).get(0).get(columnName);
14 | if(columnValue == null || columnValue.isEmpty()) {
15 | return defaultValue;
16 | }
17 | if(withQuotes) {
18 | return "\"" + String.valueOf(columnValue) + "\"";
19 | }
20 | return String.valueOf(columnValue);
21 | }
22 |
23 | /**
24 | * select count(*) from tableName;
25 | * 获取String类型的数据统计
26 | */
27 | String getTableCount(String tableName) {
28 | return vars.getObject(tableName).get(0).get("COUNT(*)").toString();
29 | }
30 |
31 |
32 |
--------------------------------------------------------------------------------
/common-util/README.md:
--------------------------------------------------------------------------------
1 | # common-util
2 | ## 项目说明
3 | - 平时写脚本时常用的方法
4 |
5 | ## 方法说明
6 | ### `org.apache.jmeter.common.random.Randoms`
7 | #### `getNumber(int length)`
8 | #### `getNumber(String str, int length)`
9 | #### `getNumber(int length, String str)`
10 | #### `getNumber(int length1, String str, int length2)`
11 | #### `getNumber(String str1, int length, String str2)`
12 | - 获取随机数
13 |
14 |
15 | #### `getIDCard()`
16 | #### `getHKIDCard()`
17 | #### `getMacaoIDCard()`
18 | #### `getTWIDCard()`
19 | - 获取身份证ID随机数
20 |
21 | #### `getIDCard15()`
22 | - 获取15位身份证ID随机数
23 |
24 | #### `getBankCard(String cardBin, int cardLength)`
25 | - 根据卡bin和卡长度随机生成银行卡卡号,卡号无需减去卡bin长度
26 |
27 | #### `getMobileNumber()`
28 | #### `getCMCCMobileNumber()`
29 | #### `getCUCCMobileNumber()`
30 | #### `getTelecomMobileNumber()`
31 | - 获取 移动/联通/电信 手机号码随机数
32 |
33 | ...
--------------------------------------------------------------------------------
/common-util/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | jmeter-plugins
7 | jmeter-plugins
8 | 5.1.1-v3
9 | ../pom.xml
10 |
11 | 4.0.0
12 |
13 | common-util
14 |
15 |
16 |
17 | org.apache.jmeter
18 | ApacheJMeter_core
19 |
20 |
21 | org.apache.jmeter
22 | ApacheJMeter_http
23 |
24 |
25 | com.google.code.gson
26 | gson
27 |
28 |
29 | redis.clients
30 | jedis
31 |
32 |
33 | com.jcraft
34 | jsch
35 |
36 |
37 | com.jayway.jsonpath
38 | json-path
39 |
40 |
41 | org.apache.commons
42 | commons-lang3
43 |
44 |
45 | org.apache.httpcomponents
46 | httpclient
47 |
48 |
49 | org.apache.httpcomponents
50 | httpcore
51 |
52 |
53 | org.apache.commons
54 | commons-text
55 |
56 |
57 | org.projectlombok
58 | lombok
59 |
60 |
61 | org.apache.poi
62 | poi
63 |
64 |
65 | org.apache.poi
66 | poi-ooxml
67 |
68 |
69 | org.yaml
70 | snakeyaml
71 |
72 |
73 | commons-codec
74 | commons-codec
75 |
76 |
77 | org.apache.logging.log4j
78 | log4j-api
79 |
80 |
81 | org.apache.logging.log4j
82 | log4j-core
83 |
84 |
85 | org.slf4j
86 | slf4j-api
87 |
88 |
89 |
90 |
91 | ${project.groupId}-${project.artifactId}-${project.version}
92 |
93 |
--------------------------------------------------------------------------------
/common-util/src/main/java/org/apache/jmeter/common/cli/CliOptions.java:
--------------------------------------------------------------------------------
1 | package org.apache.jmeter.common.cli;
2 |
3 | /**
4 | * @author Kaiwen.Ye
5 | */
6 | public class CliOptions {
7 | public static final String REPORT_DIR = "reportDir";
8 | public static final String REPORT_NAME = "reportName";
9 | public static final String IS_APPEND = "isAppend";
10 | public static final String CONFIG_NAME = "configName";
11 | }
12 |
--------------------------------------------------------------------------------
/common-util/src/main/java/org/apache/jmeter/common/encryption/Signature.java:
--------------------------------------------------------------------------------
1 | package org.apache.jmeter.common.encryption;
2 |
3 | import com.google.gson.JsonSyntaxException;
4 | import org.apache.commons.collections4.CollectionUtils;
5 | import org.apache.commons.collections4.MapUtils;
6 | import org.apache.commons.lang3.StringUtils;
7 | import org.apache.jmeter.common.json.JsonUtil;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | import java.nio.charset.StandardCharsets;
12 | import java.security.MessageDigest;
13 | import java.security.NoSuchAlgorithmException;
14 | import java.util.Comparator;
15 | import java.util.List;
16 | import java.util.Map;
17 | import java.util.TreeMap;
18 |
19 | /**
20 | * 报文加签工具类
21 | * Json报文按照 key首字母排序后用MD5加密
22 | *
23 | * @author Kelvin.Ye
24 | */
25 | public class Signature {
26 |
27 | private static final Logger log = LoggerFactory.getLogger(Signature.class);
28 |
29 | /**
30 | * 报文加签
31 | *
32 | * @param json json报文
33 | * @param prefix 加签前缀
34 | * @return 报文加签md5密文
35 | */
36 | public static String sign(String json, String prefix) throws JsonSyntaxException, NoSuchAlgorithmException {
37 | if (StringUtils.isBlank(json)) {
38 | return "";
39 | }
40 |
41 | try {
42 | StringBuffer sortedSb = new StringBuffer();
43 |
44 | // 排序Json
45 | Map