用Cactus测试Filter
用Cactus测试Filter
测试环境:Tomcat4,Cactus1.6.1
测试这样的一个Filter,它在用户登陆的时候根据客户端的信息(客户端类型,主机名)对用户身份作不同的认证。
public void doFilter(ServletRequest srReq,ServletResponse srRes,
FilterChain chain) throws ServletException, IOException {
HttpServletRequest req = null;
HttpServletResponse res = null;
try {
req = (HttpServletRequest) srReq;
res = (HttpServletResponse) srRes;
String browserType = getBrowserType(req.getHeader("User-Agent"));
if (browserType.equals("F")) {
log.debug("监视用客户端");
return;
}
param = new NspAifa();
req.setAttribute("_nsn_aifa", param.getAifaObject());
// eAIFAに共通項目を設定
String requestId = getRequestId(req);
param.put(BasicAifa.REQUEST_ID, requestId);
param.put(NspAifaKey.HT_AGENT, browserType);
UserAgent userAgent = UserAgentFactory.getUserAgent(req, param);
System.out.println(userAgent.getUrlMap());
req.setAttribute("url", userAgent.getUrlMap());
try {
// ログイン中認証を行う
userAgent.verify();
} finally {
// 認証失敗したとしても、可能な限り変数を取得する
userAgent.exportParameters(param);
}
chain.doFilter(new ConvertRequestWrapper(req, param), res);
} catch (SystemException e) {
e.log(log, param);
dispatchError(e, chain, req, res);
} catch (SystemRuntimeException e) {
e.log(log, param);
dispatchError(e, chain, req, res);
} catch (RuntimeException e) {
sre.log(log, param);
dispatchError(sre, chain, req, res);
}
}
public static UserAgent getUserAgent(HttpServletRequest req,NspParameter param, int type)
throws DecryptException {
String serverName = req.getServerName().toLowerCase();
if (serverName.equals("www.host1.com")) {
return new SecCodeUserAgent(req, param, type);
} else if (serverName.equals("www.host2.com")) {
return new DemoUserAgent(req, param, type);
} else if (serverName.equals("www.host3.com")) {
return new X509UserAgent(req, param, type);
} else if (serverName.equals("www.host4.com")) {
return new CugUserAgent(req, param, type);
} else if (serverName.equals("www.host5.com")) {
String agentName = req.getHeader("User-Agent");
if ((agentName != null) && agentName.startsWith("DoCoMo/2")) {
return new FomaUserAgent(req, param, type);
}
return new IModeUserAgent(req, param, type);
} else if (serverName.equals("p246-1.jskypl.jp-t.ne.jp")) {
return new JSkyUserAgent(req, param, type);
} else if (serverName.equals("nst.kddi.ne.jp")) {
return new EzWebUserAgent(req, param, type);
} else if (serverName.equals("lmodet.ns.e.pipopa.ne.jp")) {
return new LModeUserAgent(req, param, type);
} else if (
serverName.endsWith(".secure.bpr.nomura.co.jp")
|| serverName.endsWith(".intranet.jp.nomura.com")) {
return new WOPUserAgent(req, param, type);
} else if (log.isDebugEnabled()) {
String agentName = req.getHeader("User-Agent");
if (agentName.startsWith("DoCoMo/1")) {
return new IModeUserAgent(req, param, type);
} else if (agentName.startsWith("DoCoMo/2")) {
return new FomaUserAgent(req, param, type);
} else if (agentName.startsWith("J-PHONE")) {
return new JSkyUserAgent(req, param, type);
} else if (agentName.startsWith("Vodafone")) {
return new JSkyUserAgent(req, param, type);
}
}
throw new SystemRuntimeException(ErrorInfo.RT_UNKNOWN_HOST,new String[]{serverName});
}
在web.xml中的<web-app>标签中如下配置Filter:
<filter>
<filter-name>FilterRedirector</filter-name>
<filter-class>org.apache.cactus.server.FilterTestRedirector</filter-class>
</filter>
<filter>
<filter-name>NextFilter</filter-name>
<filter-class>jp.co.nri.nsp.pl.NextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterRedirector</filter-name>
<url-pattern>/FilterRedirector</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>NextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
前面两个是Filter的声明,其中FilterRedirector是Cactus进行Filter测试所必需的,NextFilter是在测试Filter类的时候,
首先定义一个beginXXX()方法,这个方法在Cactus模拟的客户端在request里设置参数值,注意方法的参数的类型是org.apache.cactus.WebRequest。
public final void beginDoFilterSecCodeUserAgent(final WebRequest req) {
// 设定request头"User-Agent"
req.addHeader("User-Agent", "Mozilla/4.0");
// 设定request头"ServerName"
req.addHeader("Host", "http://www.sum.com");
// 设定request参数userName
req.addParameter("userName", "Russell Crowe");
// 设定request加密的参数password
req.addParameter("password", Crypto.encrypt("123456"));
}
除了字符串以外,WebRequest的addParameter方法无法将其他对象放进去,而他又没有像HttpServletRequest的setAttribute的方法,但是对于数组这种对象还是可以通过连续add相同key的方法在WebRequest中形成数组:
req.addParameter("Key", "aaa");
req.addParameter("Key", "bbb");
然後在testXXX()方法中可以将数组取出
Map map = request.getParameterMap();
String[] params = map.get("Key");
如果要放入对象,可以在testXXX里写
//把一个对象放到request里
Object o = new Object();
super.request.setAttribute(o);
注意不要将null放进去,否则会引发NullPointer异常。
在setup方法中实例化被测试类:
public final void setUp() throws Exception {
testClass = new XXXFilter();
testClass.init(config);
}
测试doFilter方法:
public final void testDoFilterSecCodeUserAgent() {
testClass.doFilter();
}
注意1:addParameter方法无法将null放进去,否则会引发NullPointer异常
注意2:如果被测Class程序流程受静态变量影响,则无法在单个测试Class中测试所有的分支,需要分多个Class
注意3:如果测试过程中有需要修改Properties的Case的话,只能将每个此类的Case放到单独的测试类中测试,Tomcat在Cactus执行同一测试类的时候无法将Properties文件重新加载
浙公网安备 33010602011771号