最近,群里的牛肉面大神有個需求,是將每個post請求的body部分做一個加密操作,其實這個需求不算難,用beanshell引入加密函數的包,然后調用就行了。只是,如果請求多了,每次都要調用一下自己加密函數,有點麻煩,也不利於給team內部其他人員,解決方法是把這個加密函數加到函數助手中去,這里我采用的方法是,將jmeter3.0的源代碼下載下來,引入到eclipse當中,找到函數助手的包名,然后添加對應的java文件,編譯,打包,再貼回到$JMETER_HOME/lib/ext/下面。網上有部分教程,但是不是很全,有些地方也沒有說明白,這里我整理一下。
另外,國外的網站上說有另外一種方法,是直接寫一個加密函數的java文件,包名必須名為.functions后綴,然后單獨打成jar包放到$JMETER_HOME/lib/ext/,這種方法可能簡單一點,然而我並沒有調試成功,如果有成功的朋友可以在下方留言。
我自己的方法步驟及代碼如下(關鍵部分代碼隱去):
- 環境准備:
eclipse,這個就不細說了。
Jmeter3.0的源碼,下載地址是:http://jmeter.apache.org/download_jmeter.cgi,頁面上下載apache-jmeter-3.0_src.zip並解壓到硬盤即可。
這里有沒有ant不重要,我們這里只需要對函數助手打包即可。
- 把Jmeter源碼導入到eclipse:
不能按照普通的導入java項目的方法導入。導入步驟如下:
第一步:新建一個java項目,比如名字叫jmeter
第二步:打開jmeter項目存放位置,關閉eclipse,刪除jmeter目錄下bin和src兩個文件夾
第三步:修改.classpath文件:編輯.classpath文件,用apache-jmeter-3.0_src解壓文件夾中的eclipse.classpath內容替換之。
第四部:重新打開eclipse,利用import導入源代碼。
導入過后應該是這樣的:
第五步:修改依賴,在build path中修改依賴包,加入$JMETER_HOME/lib下所有的jar包,同時加入$JMETER_HOME/lib/ext/ApacheJMeter_components.jar和$JMETER_HOME/lib/ext/ApacheJMeter_core.jar。
這樣差不多項目前面的感嘆號就消失了。
到此,倒入jmeter源代碼的工作就完成了,我們可以加入代碼。
- 找到src/functions,這里存放了所有函數助手中包含的函數:
- 我們這里增加一個java文件,我這里命名為AbbottEncry.java,關於依賴,可以參考下其他的java文件怎么寫的,貼進去就行了,當然也要引入你的方法需要用的jar包,比如我這里的加密所用的jar包。
具體代碼如下:代碼實現部分省略,前后的定義放出來供大家參考。

1 package org.apache.jmeter.functions; 2 3 import java.util.Collection; 4 import java.util.LinkedList; 5 import java.util.List; 6 7 import org.apache.jmeter.engine.util.CompoundVariable; 8 import org.apache.jmeter.samplers.SampleResult; 9 import org.apache.jmeter.samplers.Sampler; 10 import org.apache.jmeter.threads.JMeterVariables; 11 import org.apache.jmeter.util.JMeterUtils; 12 import net.heyfinance.aes.AesCryptUtil; 13 import net.sf.json.JSONObject; 14 15 /** 16 * for Abbott 17 * 18 * 19 */ 20 public class AbbottEncry extends AbstractFunction { 21 22 // private static final String CHARSET_ENCODING = "UTF-8"; //$NON-NLS-1$ 23 24 private static final List<String> desc = new LinkedList<>(); 25 26 private static final String KEY = "__AbbottEncry"; 27 //這個是在函數助手上顯示的函數名稱 28 29 static { 30 desc.add(JMeterUtils.getResString("src_body")); 31 desc.add(JMeterUtils.getResString("base_args")); 32 desc.add(JMeterUtils.getResString("encrtion_key")); 33 desc.add(JMeterUtils.getResString("encr_body")); 34 /* 35 這里4個參數,就是我們在調用函數助手時,輸入的參數,這里有4個 36 src_body = 要加密的串串 37 base_args = 另外一條要加密的串串 38 encrtion_key = 加密用的key 39 encr_body = 加密后想存在jmeter中的參數名 40 */ 41 } 42 43 private Object[] values; 44 public AbbottEncry() { 45 } 46 47 /** {@inheritDoc} */ 48 @Override 49 public String execute(SampleResult previousResult, Sampler currentSampler) 50 throws InvalidVariableException { 51 JSONObject jsonThree = new JSONObject(); 52 String encrString = ""; //$NON-NLS-1$ 53 String varName = ((CompoundVariable) values[values.length - 1]).execute().trim(); 54 JMeterVariables vars = getVariables(); 55 56 57 String srcBody = ((org.apache.jmeter.engine.util.CompoundVariable) values[0]).execute(); 58 String baseArgs = ((org.apache.jmeter.engine.util.CompoundVariable) values[1]).execute(); 59 String encrKey = ((org.apache.jmeter.engine.util.CompoundVariable) values[2]).execute(); 60 //把參數轉換成String 61 62 //此處略去。。。 63 64 return encrString; 65 } 66 67 /** {@inheritDoc} */ 68 @Override 69 public void setParameters(Collection<CompoundVariable> parameters) throws InvalidVariableException { 70 checkParameterCount(parameters, 3, 4); 71 //這里,后面的3,4是指調用函數助手時,可以接受的參數個數,低於3就不會執行(這個地方,可能解釋不是很明確,后面再去看下官檔) 72 values = parameters.toArray(); 73 //把接受到的參數裝成array,然后用value[i]取出來。 74 } 75 76 /** {@inheritDoc} */ 77 @Override 78 public String getReferenceKey() { 79 return KEY; 80 } 81 82 /** {@inheritDoc} */ 83 @Override 84 public List<String> getArgumentDesc() { 85 return desc; 86 } 87 }
- 寫完了以后我們可以打包了,右鍵src/functions用export功能達成jar包,注意3.0后,函數助手的名字叫ApacheJMeter_functions.jar。打成jar包后,放到$JMETER_HOME/lib/ext/注意備份一下原來文件。
另外,自己的函數依賴包要放到$JMETER_HOME/lib。
- 重新啟動Jmeter就行了,我們可以看到我們需要的函數了。這里還有個小bug,暫時不知道原因,第一次進去函數助手,看到自己的函數的時候,發現參數列表是空的,我以為是程序問題,但是選擇一個別的函數,然后再選回到自己的函數上,參數又出現了,並且可以正常使用,暫時不知道原因,有興趣的朋友可以討論下。
至此,文章結束。