├── BeanShell-demo ├── image │ ├── http-header-manager.PNG │ ├── main-lib-config-path.PNG │ ├── BeanShellPostProcessor.PNG │ ├── BeanShellPreProcessor.PNG │ ├── user-defined-variables.PNG │ └── loginByOtp-请求-响应-加密-data字段出现.PNG ├── BeanShellPreProcessorDemo.java ├── BeanShellPostProcessorDemo.java └── 测试计划app.jmx ├── .gitignore ├── README.md └── LICENSE /BeanShell-demo/image/http-header-manager.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcuike/JMeter-jmx-BeanShellCode/HEAD/BeanShell-demo/image/http-header-manager.PNG -------------------------------------------------------------------------------- /BeanShell-demo/image/main-lib-config-path.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcuike/JMeter-jmx-BeanShellCode/HEAD/BeanShell-demo/image/main-lib-config-path.PNG -------------------------------------------------------------------------------- /BeanShell-demo/image/BeanShellPostProcessor.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcuike/JMeter-jmx-BeanShellCode/HEAD/BeanShell-demo/image/BeanShellPostProcessor.PNG -------------------------------------------------------------------------------- /BeanShell-demo/image/BeanShellPreProcessor.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcuike/JMeter-jmx-BeanShellCode/HEAD/BeanShell-demo/image/BeanShellPreProcessor.PNG -------------------------------------------------------------------------------- /BeanShell-demo/image/user-defined-variables.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcuike/JMeter-jmx-BeanShellCode/HEAD/BeanShell-demo/image/user-defined-variables.PNG -------------------------------------------------------------------------------- /BeanShell-demo/image/loginByOtp-请求-响应-加密-data字段出现.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sdcuike/JMeter-jmx-BeanShellCode/HEAD/BeanShell-demo/image/loginByOtp-请求-响应-加密-data字段出现.PNG -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | 3 | # Mobile Tools for Java (J2ME) 4 | .mtj.tmp/ 5 | 6 | # Package Files # 7 | *.jar 8 | *.war 9 | *.ear 10 | 11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 12 | hs_err_pid* 13 | -------------------------------------------------------------------------------- /BeanShell-demo/BeanShellPreProcessorDemo.java: -------------------------------------------------------------------------------- 1 | import com.alibaba.fastjson.JSON; 2 | import com.alibaba.fastjson.JSONObject; 3 | import sun.misc.BASE64Decoder; 4 | import sun.misc.BASE64Encoder; 5 | import javax.crypto.Cipher; 6 | import javax.crypto.spec.IvParameterSpec; 7 | import javax.crypto.spec.SecretKeySpec; 8 | import com.xx.x.util.*; 9 | import org.apache.jmeter.protocol.http.sampler.*; 10 | import org.apache.jmeter.samplers.*; 11 | import org.apache.jmeter.config.*; 12 | import org.apache.jmeter.protocol.http.sampler.*; 13 | import org.apache.jmeter.protocol.http.util.*; 14 | import java.io.FileInputStream; 15 | import java.io.FileNotFoundException; 16 | import java.io.IOException; 17 | import java.util.Properties; 18 | import com.doctor.commons.*; 19 | 20 | try { 21 | 22 | //自定义变量 23 | //读取配置.设置头信息和公共信息 24 | 25 | Properties properties = new Properties(); 26 | String fileName = ${configFile}+""; 27 | FileInputStream inputStream = new FileInputStream(fileName); 28 | properties.load(inputStream); 29 | 30 | String accountId = properties.getProperty("accountId"); 31 | String sign = properties.getProperty("sign"); 32 | String accessKey = properties.getProperty("accessKey"); 33 | String token = properties.getProperty("token"); 34 | 35 | vars.put("accountId",accountId); 36 | vars.put("sign",sign); 37 | vars.put("accessKey",accessKey); 38 | vars.put("token",token); 39 | 40 | if (inputStream != null) { 41 | inputStream.close(); 42 | } 43 | 44 | String deviceId = ${deviceId}+""; 45 | String secretKey = ${secretKey}+""; 46 | 47 | //请求体重置加密 48 | Arguments arguments = sampler.getArguments(); 49 | Argument arg = arguments.getArgument(0); 50 | String body = arg.getValue(); 51 | log.info("PreProcessor==========================================="+ body); 52 | 53 | JSONObject parseObject = JSON.parseObject(body); 54 | log.info("====********************************************************************"+ parseObject); 55 | String data = parseObject.getString("data"); 56 | 57 | if(data !=null){ 58 | log.info("====********************************************************************"+ data); 59 | 60 | //加密 61 | String encryptData = AESUtis.appAESEncrypt(data, deviceId, secretKey); 62 | log.info("encryptData====********************************************************************"+ encryptData); 63 | 64 | JSONObject jsonObject = new JSONObject(); 65 | jsonObject.put("data", encryptData); 66 | String postData = jsonObject.toJSONString(); 67 | log.info("postData====**************************************postData******************************"+ postData); 68 | 69 | //设置新post 数据 70 | arg.setValue(postData); 71 | } 72 | 73 | 74 | } catch (Exception ex) { 75 | log.info("Script execution failed===========================================", ex); 76 | } 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JMeter-jmx-BeanShellCode 2 | 3 | ### 利用自定义变量动态设置请求体 4 | ### 请求头的值合理利用自定义变量来取值 5 | ### 自定义变量的值脚本设置(从文件中读取设置) 6 | ### 利用 String fileName = ${configFile}+""; 来获取自定义变量configFile的值 7 | ### 利用 vars.put("accountId",accountId);来设置自定义变量的accountId值 8 | ### 利用以下代码模式修改请求json数据内容: 9 | Arguments arguments = sampler.getArguments(); 10 | Argument arg = arguments.getArgument(0); 11 | arg.setValue("postData"); 12 | 13 | 14 | 15 | ### 利用以下代码模式修改rest响应内容: 16 | String response_data = prev.getResponseDataAsString(); 17 | prev.setResponseData("reqDencryptJSON".getBytes("UTF-8")); 18 | 19 | ### 利用日志打印信息 20 | 21 | log.info("Script execution failed================PostProcessor=========================", exception); 22 | 23 | log.info("Script execution failed================PostProcessor========================="); 24 | 25 | ### jmeter、beanshell 官网url 26 | 27 | [https://github.com/apache/jmeter](https://github.com/apache/jmeter) 28 | [https://github.com/beanshell/beanshell](https://github.com/beanshell/beanshell) 29 | 30 | ### 利用mvn dependency:copy-dependencies -DoutputDirectory=D:/lib -DincludeScope=compile 把自定义lib的依赖包copy出来 31 | 32 | 33 | ### user-defined-variables demo 34 | 35 | ![https://raw.githubusercontent.com/sdcuike/JMeter-jmx-BeanShellCode/master/BeanShell-demo/image/user-defined-variables.PNG](https://raw.githubusercontent.com/sdcuike/JMeter-jmx-BeanShellCode/master/BeanShell-demo/image/user-defined-variables.PNG) 36 | 37 | ### lib-config-path demo 38 | 39 | ![https://raw.githubusercontent.com/sdcuike/JMeter-jmx-BeanShellCode/master/BeanShell-demo/image/main-lib-config-path.PNG](https://raw.githubusercontent.com/sdcuike/JMeter-jmx-BeanShellCode/master/BeanShell-demo/image/main-lib-config-path.PNG) 40 | 41 | 42 | ### http-header-manager demo 43 | 44 | ![https://raw.githubusercontent.com/sdcuike/JMeter-jmx-BeanShellCode/master/BeanShell-demo/image/http-header-manager.PNG](https://raw.githubusercontent.com/sdcuike/JMeter-jmx-BeanShellCode/master/BeanShell-demo/image/http-header-manager.PNG) 45 | 46 | 47 | ### BeanShellPreProcessor demo 48 | 49 | ![https://raw.githubusercontent.com/sdcuike/JMeter-jmx-BeanShellCode/master/BeanShell-demo/image/BeanShellPreProcessor.PNG](https://raw.githubusercontent.com/sdcuike/JMeter-jmx-BeanShellCode/master/BeanShell-demo/image/BeanShellPreProcessor.PNG) 50 | 51 | 52 | ### BeanShellPostProcessor demo 53 | 54 | ![https://raw.githubusercontent.com/sdcuike/JMeter-jmx-BeanShellCode/master/BeanShell-demo/image/BeanShellPostProcessor.PNG](https://raw.githubusercontent.com/sdcuike/JMeter-jmx-BeanShellCode/master/BeanShell-demo/image/BeanShellPostProcessor.PNG) 55 | 56 | 57 | ### loginByOtp demo 58 | 59 | ![https://raw.githubusercontent.com/sdcuike/JMeter-jmx-BeanShellCode/master/BeanShell-demo/image/loginByOtp-%E8%AF%B7%E6%B1%82-%E5%93%8D%E5%BA%94-%E5%8A%A0%E5%AF%86-data%E5%AD%97%E6%AE%B5%E5%87%BA%E7%8E%B0.PNG](https://raw.githubusercontent.com/sdcuike/JMeter-jmx-BeanShellCode/master/BeanShell-demo/image/loginByOtp-%E8%AF%B7%E6%B1%82-%E5%93%8D%E5%BA%94-%E5%8A%A0%E5%AF%86-data%E5%AD%97%E6%AE%B5%E5%87%BA%E7%8E%B0.PNG) 60 | -------------------------------------------------------------------------------- /BeanShell-demo/BeanShellPostProcessorDemo.java: -------------------------------------------------------------------------------- 1 | import com.alibaba.fastjson.JSON; 2 | import com.alibaba.fastjson.JSONObject; 3 | import sun.misc.BASE64Decoder; 4 | import sun.misc.BASE64Encoder; 5 | import javax.crypto.Cipher; 6 | import javax.crypto.spec.IvParameterSpec; 7 | import javax.crypto.spec.SecretKeySpec; 8 | import com.xx.x.util.*; 9 | import java.io.FileInputStream; 10 | import java.io.FileNotFoundException; 11 | import java.io.IOException; 12 | import java.util.Properties; 13 | import com.doctor.commons.*; 14 | 15 | 16 | 17 | try { 18 | 19 | //先取自定义变量,等用到的时候,再取说找不到定义 20 | String secretKey = ${secretKey}+""; 21 | String deviceId = ${deviceId}+""; 22 | //服务器返回的公共配置属性保存 23 | String fileName = ${configFile}+""; 24 | log.info("====*fileName*******************************************************************"+ fileName); 25 | 26 | 27 | //对返回的json数据处理 28 | String response_data = prev.getResponseDataAsString(); 29 | JSONObject parseObject = JSON.parseObject(response_data); 30 | log.info("====********************************************************************"+ parseObject); 31 | String data = parseObject.getString("data"); 32 | 33 | //这是加密的数据处理 34 | if (data != null) { 35 | 36 | log.info("====PostProcessor********************************************************************"+ data); 37 | //解密 38 | String reqDencryptJSON = AESUtis.appAESDencrypt(data, deviceId,secretKey ); 39 | 40 | log.info("===PostProcessor**********************************responseBody*****************************"+ reqDencryptJSON); 41 | 42 | //解密的数据写回返回body中 43 | prev.setResponseData(reqDencryptJSON.getBytes("UTF-8")); 44 | 45 | 46 | //取用户属性保存,以便以后用到 47 | JSONObject resultJson= JSON.parseObject(reqDencryptJSON); 48 | JSONObject result = resultJson.getJSONObject("result"); 49 | if (result != null) { 50 | log.info("===PostProcessor*********************************result *******===************" ); 51 | String accessKey = result.getString("accessKey"); 52 | 53 | if (accessKey != null) { 54 | String accountId = result.getString("accountId"); 55 | String token = result.getString("token"); 56 | 57 | //配置.设置头信息和公共信息 58 | 59 | 60 | String sign = MD5Utils.md5To32LowerCaseHexString( secretKey + accountId+ deviceId + secretKey); 61 | 62 | //文件读取放到这里, 文件内容会被重写,而不是追加模式,所以不能实际保存内容的地方申明FileOutputStream 63 | Properties properties = new Properties(); 64 | 65 | FileOutputStream outputStream = new FileOutputStream(fileName); 66 | 67 | properties.setProperty("accountId",accountId); 68 | properties.setProperty("accessKey",accessKey); 69 | properties.setProperty("sign",sign); 70 | properties.setProperty("token",token); 71 | properties.store(outputStream, "");// 72 | log.info("===PostProcessor**********************************properties.store*******===************" ); 73 | 74 | //资源释放 75 | 76 | 77 | if (outputStream != null) { 78 | outputStream.close(); 79 | } 80 | 81 | } 82 | } 83 | } 84 | 85 | 86 | } catch (Exception ex) { 87 | 88 | log.info("Script execution failed================PostProcessor=========================", ex); 89 | } 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /BeanShell-demo/测试计划app.jmx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | false 7 | false 8 | 9 | 10 | 11 | D:\lib 12 | 13 | 14 | 15 | 16 | 17 | false 18 | import com.alibaba.fastjson.JSON; 19 | import com.alibaba.fastjson.JSONObject; 20 | import sun.misc.BASE64Decoder; 21 | import sun.misc.BASE64Encoder; 22 | import javax.crypto.Cipher; 23 | import javax.crypto.spec.IvParameterSpec; 24 | import javax.crypto.spec.SecretKeySpec; 25 | import com.zhongan.clare.util.*; 26 | import org.apache.jmeter.protocol.http.sampler.*; 27 | import org.apache.jmeter.samplers.*; 28 | import org.apache.jmeter.config.*; 29 | import org.apache.jmeter.protocol.http.sampler.*; 30 | import org.apache.jmeter.protocol.http.util.*; 31 | import java.io.FileInputStream; 32 | import java.io.FileNotFoundException; 33 | import java.io.IOException; 34 | import java.util.Properties; 35 | import com.doctor.commons.*; 36 | 37 | try { 38 | 39 | //自定义变量 40 | //读取配置.设置头信息和公共信息 41 | 42 | Properties properties = new Properties(); 43 | String fileName = ${configFile}+""; 44 | FileInputStream inputStream = new FileInputStream(fileName); 45 | properties.load(inputStream); 46 | 47 | String accountId = properties.getProperty("accountId"); 48 | String sign = properties.getProperty("sign"); 49 | String accessKey = properties.getProperty("accessKey"); 50 | String token = properties.getProperty("token"); 51 | 52 | vars.put("accountId",accountId); 53 | vars.put("sign",sign); 54 | vars.put("accessKey",accessKey); 55 | vars.put("token",token); 56 | 57 | if (inputStream != null) { 58 | inputStream.close(); 59 | } 60 | 61 | String deviceId = ${deviceId}+""; 62 | String secretKey = ${secretKey}+""; 63 | 64 | //请求体重置加密 65 | Arguments arguments = sampler.getArguments(); 66 | Argument arg = arguments.getArgument(0); 67 | String body = arg.getValue(); 68 | log.info("PreProcessor==========================================="+ body); 69 | 70 | JSONObject parseObject = JSON.parseObject(body); 71 | log.info("====********************************************************************"+ parseObject); 72 | String data = parseObject.getString("data"); 73 | 74 | if(data !=null){ 75 | log.info("====********************************************************************"+ data); 76 | 77 | //加密 78 | String encryptData = AESOperator.getInstance().appAESEncrypt(data, deviceId, secretKey); 79 | log.info("encryptData====********************************************************************"+ encryptData); 80 | 81 | JSONObject jsonObject = new JSONObject(); 82 | jsonObject.put("data", encryptData); 83 | String postData = jsonObject.toJSONString(); 84 | log.info("postData====**************************************postData******************************"+ postData); 85 | 86 | //设置新post 数据 87 | arg.setValue(postData); 88 | } 89 | 90 | 91 | } catch (Exception ex) { 92 | log.info("Script execution failed===========================================", ex); 93 | } 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | false 108 | import com.alibaba.fastjson.JSON; 109 | import com.alibaba.fastjson.JSONObject; 110 | import sun.misc.BASE64Decoder; 111 | import sun.misc.BASE64Encoder; 112 | import javax.crypto.Cipher; 113 | import javax.crypto.spec.IvParameterSpec; 114 | import javax.crypto.spec.SecretKeySpec; 115 | import com.zhongan.clare.util.*; 116 | import java.io.FileInputStream; 117 | import java.io.FileNotFoundException; 118 | import java.io.IOException; 119 | import java.util.Properties; 120 | import com.doctor.commons.*; 121 | 122 | 123 | 124 | try { 125 | 126 | //先取自定义变量,等用到的时候,再取说找不到定义 127 | String secretKey = ${secretKey}+""; 128 | String deviceId = ${deviceId}+""; 129 | //服务器返回的公共配置属性保存 130 | String fileName = ${configFile}+""; 131 | log.info("====*fileName*******************************************************************"+ fileName); 132 | 133 | 134 | //对返回的json数据处理 135 | String response_data = prev.getResponseDataAsString(); 136 | JSONObject parseObject = JSON.parseObject(response_data); 137 | log.info("====********************************************************************"+ parseObject); 138 | String data = parseObject.getString("data"); 139 | 140 | //这是加密的数据处理 141 | if (data != null) { 142 | 143 | log.info("====PostProcessor********************************************************************"+ data); 144 | //解密 145 | String reqDencryptJSON = AESOperator.getInstance().appAESDencrypt(data, deviceId,secretKey ); 146 | 147 | log.info("===PostProcessor**********************************responseBody*****************************"+ reqDencryptJSON); 148 | 149 | //解密的数据写回返回body中 150 | prev.setResponseData(reqDencryptJSON.getBytes("UTF-8")); 151 | 152 | 153 | //取用户属性保存,以便以后用到 154 | JSONObject resultJson= JSON.parseObject(reqDencryptJSON); 155 | JSONObject result = resultJson.getJSONObject("result"); 156 | if (result != null) { 157 | log.info("===PostProcessor*********************************result *******===************" ); 158 | String accessKey = result.getString("accessKey"); 159 | 160 | if (accessKey != null) { 161 | String accountId = result.getString("accountId"); 162 | String token = result.getString("token"); 163 | 164 | //配置.设置头信息和公共信息 165 | 166 | 167 | String sign = MD5Utils.md5To32LowerCaseHexString( secretKey + accountId+ deviceId + secretKey); 168 | 169 | //文件读取放到这里, 文件内容会被重写,而不是追加模式,所以不能实际保存内容的地方申明FileOutputStream 170 | Properties properties = new Properties(); 171 | 172 | FileOutputStream outputStream = new FileOutputStream(fileName); 173 | 174 | properties.setProperty("accountId",accountId); 175 | properties.setProperty("accessKey",accessKey); 176 | properties.setProperty("sign",sign); 177 | properties.setProperty("token",token); 178 | properties.store(outputStream, "");// 179 | log.info("===PostProcessor**********************************properties.store*******===************" ); 180 | 181 | //资源释放 182 | 183 | 184 | if (outputStream != null) { 185 | outputStream.close(); 186 | } 187 | 188 | } 189 | } 190 | } 191 | 192 | 193 | } catch (Exception ex) { 194 | 195 | log.info("Script execution failed================PostProcessor=========================", ex); 196 | } 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | Content-Type 207 | application/json 208 | 209 | 210 | accessKey 211 | ${accessKey} 212 | 213 | 214 | deviceId 215 | ${deviceId} 216 | 217 | 218 | sign 219 | ${sign} 220 | 221 | 222 | v 223 | 2.2.1 224 | 225 | 226 | t 227 | 228 | 229 | 230 | osVersion 231 | 232 | 233 | 234 | osDevice 235 | 236 | 237 | 238 | token 239 | ${token} 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | host 248 | http://localhost:8089 249 | = 250 | 251 | 252 | host1 253 | http://10.253.5.112:5080/za-clare 254 | = 255 | 256 | 257 | secretKey 258 | "app.zhongAn" 259 | = 260 | 261 | 262 | configFile 263 | "user.properties" 264 | = 265 | 266 | 267 | phone 268 | 15909979599 269 | = 270 | 271 | 272 | loginName 273 | ${phone} 274 | = 275 | 276 | 277 | loginPasswd 278 | sdfdsfdsf 279 | = 280 | 281 | 282 | deviceId 283 | 168 284 | = 285 | 286 | 287 | captcha 288 | 132948 289 | = 290 | 291 | 292 | accountId 293 | 294 | = 295 | 296 | 297 | sign 298 | 299 | = 300 | 301 | 302 | accessKey 303 | 304 | = 305 | 306 | 307 | token 308 | 309 | = 310 | 311 | 312 | 313 | 314 | 315 | continue 316 | 317 | false 318 | 1 319 | 320 | 1 321 | 1 322 | 1370726934000 323 | 1370726934000 324 | false 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | true 333 | 334 | 335 | 336 | false 337 | {"loginName":"15900898998" 338 | } 339 | = 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | ${host}/app/user/isRegistered 350 | POST 351 | true 352 | false 353 | true 354 | false 355 | false 356 | 357 | 358 | 359 | 360 | true 361 | 362 | 363 | 364 | false 365 | {"loginName":"" 366 | } 367 | = 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | ${host}/app/user/isRegistered 378 | POST 379 | true 380 | false 381 | true 382 | false 383 | false 384 | 385 | 386 | 387 | 388 | true 389 | 390 | 391 | 392 | false 393 | {"loginName":"15900898998"} 394 | = 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | ${host}/app/user/existBindedPhone 405 | POST 406 | true 407 | false 408 | true 409 | false 410 | false 411 | 412 | 413 | 414 | 415 | true 416 | 417 | 418 | 419 | false 420 | {"loginName":""} 421 | = 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | ${host}/app/user/existBindedPhone 432 | POST 433 | true 434 | false 435 | true 436 | false 437 | false 438 | 439 | 440 | 441 | 442 | true 443 | 444 | 445 | 446 | false 447 | {"loginName":"88xxxjjj"} 448 | = 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | ${host}/app/user/existBindedPhone 459 | POST 460 | true 461 | false 462 | true 463 | false 464 | false 465 | 466 | 467 | 468 | 469 | true 470 | 471 | 472 | 473 | false 474 | {"loginName":"15900898998"} 475 | = 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | ${host}/app/user/getAuthenticationCategory 486 | POST 487 | true 488 | false 489 | true 490 | false 491 | false 492 | 493 | 494 | 495 | 496 | true 497 | 498 | 499 | 500 | false 501 | {"loginName":"15900898998", 502 | "requestParam":"sfj", 503 | "smsType":"4", 504 | "priority":"1", 505 | "step":"1" 506 | 507 | } 508 | = 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | ${host}/app/user/authentication 519 | POST 520 | true 521 | false 522 | true 523 | false 524 | false 525 | 526 | 527 | 528 | 529 | true 530 | 531 | 532 | 533 | false 534 | { 535 | "data": { 536 | 537 | "password": "${loginPasswd}" 538 | } 539 | } 540 | = 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | ${host}/app/user/isPasswordValid 551 | POST 552 | true 553 | false 554 | true 555 | false 556 | false 557 | 558 | 559 | 560 | 561 | true 562 | 563 | 564 | 565 | false 566 | { 567 | "data": { 568 | "phone": "${phone}", 569 | "loginPasswd": "${loginPasswd}" 570 | } 571 | } 572 | = 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | ${host}/app/member/setLoginPasswdWhenAutoRegisterByPhone 583 | POST 584 | true 585 | false 586 | true 587 | false 588 | false 589 | 590 | 591 | 592 | 593 | true 594 | 595 | 596 | 597 | false 598 | {"phone":"15909909998", 599 | "captcha":"sfj1235" 600 | } 601 | = 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | ${host}/app/member/loginByOtp 612 | POST 613 | true 614 | false 615 | true 616 | false 617 | false 618 | 619 | 620 | 621 | 622 | true 623 | 624 | 625 | 626 | false 627 | {"loginName":"15900898998", 628 | "requestParam":"", 629 | "priority":"", 630 | "step":"", 631 | "authenticationType":"0" 632 | } 633 | = 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | ${host}/app/user/authentication 644 | POST 645 | true 646 | false 647 | true 648 | false 649 | false 650 | 651 | 652 | 653 | 654 | true 655 | 656 | 657 | 658 | false 659 | {"loginName":"15900898998", 660 | "requestParam":"11221", 661 | "priority":"2", 662 | "step":"1", 663 | "authenticationType":"0" 664 | } 665 | = 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | ${host}/app/user/authentication 676 | POST 677 | true 678 | false 679 | true 680 | false 681 | false 682 | 683 | 684 | 685 | 686 | true 687 | 688 | 689 | 690 | false 691 | {"loginName":""} 692 | = 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | ${host}/app/user/getAuthenticationCategory 703 | POST 704 | true 705 | false 706 | true 707 | false 708 | false 709 | 710 | 711 | 712 | 713 | true 714 | 715 | 716 | 717 | false 718 | {"loginName":"resultMap"} 719 | = 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | ${host}/app/user/getAuthenticationCategory 730 | POST 731 | true 732 | false 733 | true 734 | false 735 | false 736 | 737 | 738 | 739 | 740 | true 741 | 742 | 743 | 744 | false 745 | {"loginName":"resultMap", 746 | "phone":"12345678909"} 747 | = 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | ${host}/app/user/bindPhone 758 | POST 759 | true 760 | false 761 | true 762 | false 763 | false 764 | 765 | 766 | 767 | 768 | true 769 | 770 | 771 | 772 | false 773 | {"loginName":"", 774 | "phone":"15900898998"} 775 | = 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | ${host}/app/user/bindPhone 786 | POST 787 | true 788 | false 789 | true 790 | false 791 | false 792 | 793 | 794 | 795 | 796 | true 797 | 798 | 799 | 800 | false 801 | {"loginName":"ssresf", 802 | "phone":"15900898998"} 803 | = 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | ${host}/app/user/bindPhone 814 | POST 815 | true 816 | false 817 | true 818 | false 819 | false 820 | 821 | 822 | 823 | 824 | true 825 | 826 | 827 | 828 | false 829 | {"loginName":"15900898998", 830 | "phone":"15900898998"} 831 | = 832 | 833 | 834 | 835 | 836 | 837 | 838 | 839 | 840 | 841 | ${host}/app/user/send 842 | POST 843 | true 844 | false 845 | true 846 | false 847 | false 848 | 849 | 850 | 851 | 852 | true 853 | 854 | 855 | 856 | false 857 | {"phoneNo":"15900898998", 858 | "type":"4"} 859 | = 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | ${host}/app/user/sendCaptcha 870 | POST 871 | true 872 | false 873 | true 874 | false 875 | false 876 | 877 | 878 | 879 | 880 | true 881 | 882 | 883 | 884 | false 885 | {"phone":${phone}, 886 | "loginPasswd":"sfj1235" 887 | } 888 | = 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | ${host}/app/member/setLoginPasswdWhenAutoRegisterByPhone 899 | POST 900 | true 901 | false 902 | true 903 | false 904 | false 905 | 906 | 907 | 908 | 909 | 910 | false 911 | 912 | saveConfig 913 | 914 | 915 | true 916 | true 917 | true 918 | 919 | true 920 | true 921 | true 922 | false 923 | false 924 | true 925 | false 926 | false 927 | false 928 | false 929 | true 930 | false 931 | false 932 | true 933 | true 934 | 0 935 | true 936 | true 937 | true 938 | true 939 | 940 | 941 | 942 | 943 | 944 | 945 | continue 946 | 947 | false 948 | 1 949 | 950 | 1 951 | 1 952 | 1476927089000 953 | 1476927089000 954 | false 955 | 956 | 957 | 958 | 959 | 960 | true 961 | 962 | 963 | 964 | false 965 | { 966 | "data": { 967 | "phone": "${phone}", 968 | "captcha": "${captcha}" 969 | } 970 | } 971 | = 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 981 | ${host}/app/member/loginByOtp 982 | POST 983 | true 984 | false 985 | true 986 | false 987 | false 988 | 989 | 990 | 991 | 992 | false 993 | 994 | saveConfig 995 | 996 | 997 | true 998 | true 999 | true 1000 | 1001 | true 1002 | true 1003 | true 1004 | true 1005 | false 1006 | true 1007 | true 1008 | false 1009 | false 1010 | false 1011 | true 1012 | false 1013 | false 1014 | false 1015 | true 1016 | 0 1017 | true 1018 | true 1019 | true 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | 1027 | continue 1028 | 1029 | false 1030 | 1 1031 | 1032 | 1 1033 | 1 1034 | 1476946991000 1035 | 1476946991000 1036 | false 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | true 1043 | 1044 | 1045 | 1046 | false 1047 | {"phoneNo":"${phone}", 1048 | "type":"6" 1049 | 1050 | } 1051 | = 1052 | 1053 | 1054 | 1055 | 1056 | 1057 | 1058 | 1059 | 1060 | 1061 | ${host}/app/user/sendCaptcha 1062 | POST 1063 | true 1064 | false 1065 | true 1066 | false 1067 | false 1068 | 1069 | 1070 | 1071 | 1072 | false 1073 | 1074 | saveConfig 1075 | 1076 | 1077 | true 1078 | true 1079 | true 1080 | 1081 | true 1082 | true 1083 | true 1084 | true 1085 | false 1086 | true 1087 | true 1088 | false 1089 | false 1090 | false 1091 | true 1092 | false 1093 | false 1094 | false 1095 | true 1096 | 0 1097 | true 1098 | true 1099 | true 1100 | 1101 | 1102 | 1103 | 1104 | 1105 | 1106 | 1107 | 1108 | 1109 | --------------------------------------------------------------------------------