Struts2中的方法过滤
????? 在默认情况下,如果我们为某个Action定义了拦截器,则这个拦截器拦截该Action内的所有方法。在有些情况下,我们只要拦截特定某些特定的方法,此时就需要使用Struts2拦截器的方法过滤特性。
?
?
????? 实现Struts2的方法过滤特性其实和普通的拦截器逻辑相似,只是普通的拦截器需要重写intercept方法,而方法过滤器需要重写doIntercept方法。
????? 实现方法过滤器:继承MethodInterceptor抽象类,并重写doIntercept方法。
????? 在MethodFilterInterceptor抽象类中,额外增加了两个方法:
????? |-public void setExcludeMethods(String excludeMethods):排除需要过滤的方法,即设置方法“黑名单”,所有在excludeMethods字符串中列出的方法都不会被拦截。
????? |-public void setIncludeMethods(String includeMethods):设置需要过滤的方法,即设置方法“白名单”,所有在includeMethods字符串中列出的方法都会被拦截。
????? 注:如果一个方法同时在excludeMethods和includeMethods中列出,则该方法会被拦截。
?
下面还以简单的登录为例演示:
1、编写登录页面,和普通拦截器一样
login.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>登录页面</title> <script type="text/javascript"> function register(){ //获取jsp页面中的一个表单元素 targetForm = document.form1; //动态修改目标表单的ation属性 targetForm.action = "login!register.action"; //提交表单 targetForm.submit(); } </script> </head> <body> <form name="form1" action="login.action" method="post"> <table align="center"> <caption>用户登录</caption> <tr> <td>用户名:</td> <td><input type="userName" name="userName"/></td> </tr> <tr> <td>密 码:</td> <td><input type="password" name="password"/></td> </tr> <tr align="center"> <td colspan="2"> <input type="submit" value="登录"/> <input type="button" onClick="javascript:register();" value="注册"/> </td> </tr> </table> </form> </body></html>?
?
2、编写pojo类UserBean.java和登录Action,和普通拦截器一样
UserBean.java:
package com.lee.action;/** * @author lijunjie */import java.text.SimpleDateFormat;import java.util.Date;public class UserBean {private String userName;private String password;private String tip;public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getTip() {return tip;}public void setTip(String tip) {this.tip = tip;}}?
?
LoginAction.java:
package com.lee.action;/** * @author lijunjie */import java.sql.SQLException;import com.opensymphony.xwork2.ActionSupport;import com.opensymphony.xwork2.ModelDriven;public class LoginAction extends ActionSupport implements ModelDriven<UserBean> {private UserBean model = new UserBean();@Overridepublic String execute() throws Exception {System.out.println("开始执行execute()");if("sortec".equals(model.getUserName()) && "sortec".equals(model.getPassword())){this.getModel().setTip("服务器提示:登录成功...嘎嘎");return SUCCESS;}else{return ERROR;}}public void hello(){System.out.println("hello...");}public UserBean getModel() {return model;}}?
?
?
3、编写方法过滤拦截器:
MyMethodFilterInterceptor:
package com.lee.action;/** * 方法过滤的拦截器,应该继承MethodFilterInterceptor抽象类 * @author lijunjie */import java.util.Date;import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;public class MyMethodFilterInterceptor extends MethodFilterInterceptor {//简单拦截器的名字private String name;//为简单拦截器设置名字的setter方法public void setName(String name) {this.name = name;}//重写doIntercept方法,实现对Action的拦截逻辑@Overrideprotected String doIntercept(ActionInvocation invocation) throws Exception {//取得被拦截的ActionLoginAction action = (LoginAction)invocation.getAction();System.out.println(name+"====拦截器的动作--------"+"开始执行登录Action的时间:"+new Date());//取得开始执行Action的时间long start = System.currentTimeMillis();//执行该拦截器的后一个拦截器,或者直接指定Action的execute()方法String result = invocation.invoke();System.out.println(name+"====拦截器的动作---------"+"执行完登录Action的时间:" +new Date());//取得执行完的时间long end = System.currentTimeMillis();System.out.println(name+"====拦截器的动作---------"+"执行登录共耗时"+(end-start)+" 毫秒");return result;}}?
?
4、编写struts.xml文件:
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"><struts> <include file="struts-default.xml"/> <package name="lee" extends="struts-default"> <interceptors> <!-- 配置方法过滤的拦截器 --> <interceptor name="myMethodFilter" name="code">开始执行execute()
?
?
通过以上输出信息可以验证,通过excludeMethods属性指定的execute方法无需被拦截。
此时,如果需要指定多个不被拦截器拦截,则多个方法之间应以英文逗号(,)隔开,如下配置片段
<interceptor-ref name="myMethodFilter"> <!-- 重新指定name属性的属性值 --> <param name="name">改名后的方法过滤拦截器</param> <!-- 指定execute方法不需要被拦截 --> <param name="excludeMethods">execute,hello</param> </interceptor-ref>
?
?
?? 上面的配置片段效果是:execute方法和hello方法都不会被myMethodFilter拦截器拦截
?? 注:如果excludeMethods参数和includeMethods参数同时指定了一个方法名,则拦截器会拦截该方法,如下配置片段中execute方法会被拦截:
?
<interceptor-ref name="myMethodFilter"> <!-- 重新指定name属性的属性值 --> <param name="name">改名后的方法过滤拦截器</param> <!-- 指定execute方法不需要被拦截 --> <param name="excludeMethods">execute,hello</param> <param name="includeMethods">execute</param> </interceptor-ref>
?此时输出结果:
改名后的方法过滤拦截器====拦截器的动作--------开始执行登录Action的时间:Fri Apr 30 11:04:42 CST 2010开始执行execute()改名后的方法过滤拦截器====拦截器的动作---------执行完登录Action的时间:Fri Apr 30 11:04:42 CST 2010改名后的方法过滤拦截器====拦截器的动作---------执行登录共耗时33 毫秒
?
证明execute()方法被拦截了。。。