拦载器
1.什么是拦截器?
拦截器Filter是Struts2的核心。
Struts2的拦截器与Servlet中的过滤器相似。
在执行Action的execute()方法之前,Struts2先执行struts.xml中引用的拦截器,在执行完所有引用的拦载器的doIntercept()方法后,会执行Action的execute()方法。在Struts2的拦截器体系中,Struts2的内建拦截器完成了该框架的大部分操作,所以在实际的开发过程中通常是使用系统的拦截器。
回家过程:
地铁要检查----拦截1
高铁要检查----拦截2
检票 ------拦截3
……
2.拦截器的实现原理
Struts2拦截器的实现原理相对简单,当请求Action时,Struts2会查找配置文件(struts.xml),并根据其配置实例化相对的拦截器对象,然后串成一个列表,最后一个一个地调用列表中的拦截器。
3.拦截器什么时候执行?
拦截器在Action类对象创建之后,execute()方法调用之前之后执行。
响应到客户端之前。
4.拦截器的分类
- 系统拦截器(默认拦截器)
- 自定义拦截器
当系统拦截器满足不了需求,就要自定义拦截器。
5.系统拦截器
系统拦截器的位置?
系统拦截器有很多,这里重点讲解:Timer和Token
struts-default.xml中intercept有很多系统拦截器。
5.1 Timer 时间拦截器
测试方法执行的时间。
配置代码:
<action name="person" class="com.action.PersonAction"> <result>/success.jsp</result> <!--系统时间拦截器--> <interceptor-ref name="timer"></interceptor> <!--系统拦截器栈,使用拦载器一定要带这个栈才生效,这是个好习惯--> <interceptor-ref name="defaultStack"></interceptor> </action> |
说明:
当访问PersonAction类里所有方法之前,都会触发Timer拦截器,该拦截器显示方法执行消耗时间秒。
运行后发现并没有显示什么时间,原因是2.3缺少了commons-logging-1.1.jar包,项目中加入该包后再测试。
5.2 Token 令牌拦截器
解决表单重复提交问题。
办法一:重定向,不让地址栏出现action地址。(这里不再描述)
办法二:令牌,进Action要令牌(当天的火车票,进站时、出站时用,再想进站就要有新的票了)
令牌实现步骤:
第一步:在表单中使用<s:token> 会随机产生的一个字符串,隐藏的文本域。
<form action="" method="post"> <s:token></s:token> …… </form> |
第二步:在struts.xml中配置令牌的拦截器
<action name="person*" class="com.action.PersonAction"> <result>/success.jsp</result> <!--令牌拦截器--> <interceptor-ref name="token"> <!--这里可以配置token拦截器的排队方法--> <!-- param name="excludeMethods">...</param --> </interceptor> <!-- 当出现重复提交时,自动跳转到err.jsp --> <result name="invalid.token">/err.jsp</result> <interceptor-ref name="defaultStack"></interceptor-ref> </action> |
可在页面中添加<s:actionerror>显示重复提交信息。
6.自定义拦截器
- 创建类,继承MethodFilterInterceptor类,并重写方法,方法中写业务逻辑
public class MyFilter extends MethodFilterInterceptor {
@Override protected String doIntercept(ActionInvocation invocation) throws Exception { // TODO Auto-generated method stub
ActionContext act = invocation.getInvocationContext(); //获得session Map session = act.getSession(); User user = (User)session.get("user"); ……
//通过放行 invocation.invoke(); return "success"; } } |
先在拦截器doIntercept()方法中获取parameters对象:
Map paramMap = invocation.getInvocationContext().getParameters();
然后用parameters对象获取参数(是一个字符串数组):
String[] names = (String[]) paramMap.get("user.user_name");
String username=names[0];
- 配置拦截器
<struts> <package name="mypack" extends="struts-default"> <!--1. 声明自定义拦截器--> <interceptors> <interceptor name="loginInterceptor" class="com.interceptor.LoginInterceptor"></interceptor> </interceptors> <action name="login" class="com.zking.LoginAction"> <result name="success">success.jsp</result> <!--2. Action中引用自定义拦截器--> <interceptor-ref name="loginInterceptor"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </action> </package> </struts> |
配置action里面某些方法不进行拦截:
<interceptor-ref name="loginInterceptor"> <!-- 忽略某些方法 --> <param name="excludeMethods">login,add</param> </interceptor-ref> |