1. 例子由以下幾個(gè)文件組成:
AuthorizenFilter.java,過(guò)濾器負(fù)責(zé)檢驗(yàn)session中是否存在用戶(hù)信息。如果沒(méi)有,那么轉(zhuǎn)向到 login.jsp。它的主要方法 doFilter 內(nèi)容如下:
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
HttpSession session= req.getSession();
User user = (User)session.getAttribute("user");
if(null == user){
String uri= req.getRequestURI();
//如果請(qǐng)求頁(yè)是登錄頁(yè),不轉(zhuǎn)向
if( uri.equalsIgnoreCase("/gWeb/login.jsp")){
chain.doFilter(request, response);
} else{
res.sendRedirect("/gWeb/login.jsp");
}
}else{
chain.doFilter(request, response);
}
}
User.java,用戶(hù)類(lèi)負(fù)責(zé)記錄用戶(hù)的信息。為了簡(jiǎn)化,這里的登錄操作只允許指定用戶(hù)名和密碼。主要內(nèi)容如下:
public class User {
private String user;
private String pwd;
public User(String user, String pwd) {
this.user = user;
this.pwd = pwd;
}
public boolean login(){
return user.equals("foxgem") && pwd.equals("12345678");
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
}
Login.jsp 和welcome.jsp。其中 login.jsp 負(fù)責(zé)生成 User 對(duì)象,并調(diào)用 User 的login。當(dāng) login 返回為 true 時(shí)轉(zhuǎn)向到 welcome.jsp。其驗(yàn)證部分的代碼:
<%
if( request.getParameter("Submit") != null) {
User ur= new User( request.getParameter("user"), request.getParameter("pwd"));
if( ur.login()){
session.setAttribute("user", ur);
response.sendRedirect("/gWeb/welcome.jsp");
} else{
session.setAttribute( "LOGIN_ERROR_MSG",
"無(wú)效的用戶(hù),可能原因:用戶(hù)不存在或被禁用。");
response.sendRedirect("/gWeb/index.jsp");
return;
}
}
%>
web.xml,配置 filter 攔截所有訪(fǎng)問(wèn) JSP 頁(yè)面的請(qǐng)求:
<filter>
<filter-name>authorizen</filter-name>
<filter-class>org.foxgem.jmeter.AuthorizenFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>authorizen</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
2. 創(chuàng)建如下結(jié)構(gòu)的Web測(cè)試計(jì)劃:
其中主要測(cè)試元件說(shuō)明如下:
http請(qǐng)求默認(rèn)值負(fù)責(zé)記錄請(qǐng)求的默認(rèn)值,如服務(wù)器、協(xié)議、端口等。
第一個(gè)http請(qǐng)求,請(qǐng)求login.jsp,并附加驗(yàn)證所需要的參數(shù)(user=foxgem,pwd=12345678,Submit=Submit);其包含的響應(yīng)斷言驗(yàn)證url中包含"welcome.jsp",這一點(diǎn)可以從程序中反應(yīng)。
第二個(gè)http請(qǐng)求,請(qǐng)求是welcome.jsp;其包含的響應(yīng)斷言驗(yàn)證響應(yīng)文本中包含"foxgem",它是welcome.jsp頁(yè)面邏輯的一部分。
http cookie管理器負(fù)責(zé)管理整個(gè)測(cè)試過(guò)程中使用的cookie,它不需要設(shè)置任何屬性。
循環(huán)控制器設(shè)置發(fā)送第二個(gè)請(qǐng)求的循環(huán)次數(shù),表格監(jiān)聽(tīng)器負(fù)責(zé)收集和顯示第二個(gè)請(qǐng)求的測(cè)試結(jié)果。
啟動(dòng)測(cè)試計(jì)劃之后,執(zhí)行的順序是:首先,第一個(gè)請(qǐng)求登錄頁(yè)進(jìn)行登錄;成功登錄之后,使用循環(huán)控制器執(zhí)行第二個(gè)請(qǐng)求。請(qǐng)求welcome.jsp時(shí),響應(yīng)斷言用來(lái)驗(yàn)證是否確實(shí)是welocme.jsp來(lái)處理請(qǐng)求,而不是因?yàn)槠渌?yè)。在這個(gè)測(cè)試計(jì)劃中需要注意的是http cookie管理器。正是由于它的作用,使得第二個(gè)請(qǐng)求能順利的發(fā)送到welcome.jsp進(jìn)行處理,而不是因?yàn)槿鄙儆脩?hù)安全信息轉(zhuǎn)發(fā)到login.jsp。
在這個(gè)例子中,我們并沒(méi)有在程序中使用cookie(使用的是session),那么http cookie管理器怎么會(huì)起作用呢?這是因?yàn)樵趕ervlet/jsp規(guī)范中對(duì)于session的狀態(tài)跟蹤有2種方式:
使用cookie,保留和傳遞sessionid。它不要求程序?qū)τ趗rl有什么特殊的處理,但是要求瀏覽器允許cookie。在這個(gè)例子中,是這種情形。
使用url重寫(xiě),每次顯式的在瀏覽器和服務(wù)器之間傳遞sessionid。它要求程序?qū)rl進(jìn)行編碼,對(duì)瀏覽器沒(méi)有要求。
對(duì)于第二種情形,可以使用JMeter前置管理器中的http url重寫(xiě)修飾符來(lái)完成。對(duì)于Tomcat,Session參數(shù)是jsessionid,路徑擴(kuò)展使用";"。使用url編碼時(shí)需要注意,必須將瀏覽器的cookie功能關(guān)閉。因?yàn)閡rl編碼函數(shù),如encodeURL,會(huì)判斷是否需要將sessionid編碼到url中。當(dāng)瀏覽器允許cookie時(shí),不會(huì)進(jìn)行編碼。
如果cookie而不是session來(lái)保存用戶(hù)安全信息,那么直接使用http cookie管理器行了。此時(shí),需要將使用的cookie參數(shù)和值直接寫(xiě)到管理器中,由它負(fù)責(zé)管理。對(duì)于其它的cookie使用,也是如此操作。
登錄問(wèn)題解決之后,對(duì)于 Web 服務(wù)器的測(cè)試沒(méi)什么難點(diǎn)了。剩下的是根據(jù)實(shí)際需要,靈活運(yùn)用相關(guān)的測(cè)試組件搭建編寫(xiě)的測(cè)試計(jì)劃。(當(dāng)然,對(duì)于安全問(wèn)題還有其它的使用情景。在使用時(shí)需要明確:JMeter 是否支持,如果支持使用哪種測(cè)試組件解決。)
數(shù)據(jù)庫(kù)服務(wù)器
數(shù)據(jù)庫(kù)服務(wù)器在大多數(shù)企業(yè)項(xiàng)目中是不可缺少的,對(duì)于它進(jìn)行壓力測(cè)試是為了找出:數(shù)據(jù)庫(kù)對(duì)象是否可以有效地承受來(lái)自多個(gè)用戶(hù)的訪(fǎng)問(wèn)。這些對(duì)象主要是:索引、觸發(fā)器、存儲(chǔ)過(guò)程和鎖。通過(guò)對(duì)于SQL語(yǔ)句和存儲(chǔ)過(guò)程的測(cè)試,JMeter 可以間接的反應(yīng)數(shù)據(jù)庫(kù)對(duì)象是否需要優(yōu)化。
JMeter 使用 JDBC 發(fā)送請(qǐng)求,完成對(duì)于數(shù)據(jù)庫(kù)的測(cè)試。一個(gè)數(shù)據(jù)庫(kù)測(cè)試計(jì)劃,建立如下結(jié)構(gòu)即可:
其中:
JDBC連接配置,負(fù)責(zé)配置數(shù)據(jù)庫(kù)連接相關(guān)的信息。如:數(shù)據(jù)庫(kù)url、數(shù)據(jù)庫(kù)驅(qū)動(dòng)類(lèi)名、用戶(hù)名和密碼等等。在這些配置中,"綁定到池的變量名"(Variable Name Bound to Pool)是一個(gè)非常重要的屬性,這個(gè)屬性會(huì)在JDBC請(qǐng)求中被引用。通過(guò)它, JDBC請(qǐng)求和JDBC連接配置建立關(guān)聯(lián)。(測(cè)試前,請(qǐng)將所需要的數(shù)據(jù)庫(kù)驅(qū)動(dòng)放到JMeter的classpath中)。
JDBC請(qǐng)求,負(fù)責(zé)發(fā)送請(qǐng)求進(jìn)行測(cè)試。
圖形結(jié)果,收集顯示測(cè)試結(jié)果。