Struts2为一个Action自动注入的各种功能都是通过各种拦截器实施上去的。
在<action>中使用<interceptor-ref>元素引用拦截器或拦截器栈,
在struts-default.xml文件中查看和了解默认包中的默认拦截器栈的配置。
在<package>中使用<interceptors>元素配置<interceptor>或<interceptor-stack>
在<package>中使用<default-interceptor-ref >元素为该包中的所有action配置默认拦截器 ,每个包只能指定一个默认拦截器。
一旦为某个action显式指定了某个拦截器,则所属包中定义的默认拦截器将不起作用。
ServletConfig拦截器用于调用HttpServletRequestAware、HttpServletResponseAware等接口的方法。
自定义一个进行性能统计或权限判断的拦截器,自定义拦截器要实现com.opensymphony.xwork2.interceptor.Interceptor接口。如何实现拦截器只对某些方法起作用,而对其他方法不起作用。
借助AnnotationWorkflowInterceptor用注解方式实现拦截器的功能
@Before
@BeforeResult
@After
关于自定义的拦截器,可以参看ClearSessionInterceptor和TokenInterceptor这两个拦截器的代码。
如果要在一个action上施加多个拦截器,需要多个interceptor-ref,索性定义一个拦截器组,在action中只用一个interceptor-ref来引用这个组即可。
如果没有为某个Action配置<intercept-ref/> ,那么则使用默认的拦截器组defaultStack 。一旦为某个Action配置了<intercept-ref/>,那么将不再有默认的defaultStack配置了,例如,一个实验例子是Action实现了ServletRequestAware,当增加一个自己的intercept后,在Action内部调用Request对象就不成了,只要再把ServletConfig这个拦截器配置到Action中,就又可以了。
去掉ServletConfigInterceptor拦截器,相应的Servlet API对象不再被注入到Action中。为了看到去掉ServletConfigInterceptor的效果,可以先随便指定struts2自带的一个其他的拦截器,然后再换成ServletConfigInterceptor看两种情况下的运行区别。 Struts2中的每个拦截器分别Action注入某一项功能,在Action中引用这个拦截器,Action就有了这项功能,不引入该拦截器,则没有该项功能。
ActionInvocation有一个invokeActionOnly方法,可以跳过其他Interceptor,直接去调用action,比用filter好哦。
写自己的struts2拦截器时,可以继承AbstractInterceptor,或者继承MethodFilterInterceptor(excludeMethods参数中如果有多个方法,方法之间用逗号分隔)。
用下面的代码实现一个PerformanceStatisticsInterceptor
public
String intercept(ActionInvocation invocation)
throws
Exception {
long
startTime = System.
currentTimeMillis();
String result = invocation.invoke();
long
endTime = System.
currentTimeMillis();
System.
out.println(invocation.getInvocationContext().getName() + ":" + (endTime-startTime));
return
result;
}
其中,invocation.getInvocationContext().getName()方法返回的是action在配置文件中的映射名称。由于配置了自己的拦截器后,又还要使用defaultStack这个拦截器栈,那么就再配置一个自己的拦截器栈,包含自己的拦截器和defaultStack栈,在Action中引用自己的这个栈。
权限检查拦截器的代码:
package
cn.itcast.struts2demo3.web.struts2.interceptors;
public String intercept(ActionInvocation invocation) throws Exception {
HttpSession session = ServletActionContext.getRequest().getSession();
Object user = session.getAttribute("user");
if(user == null){
return "login";
}
return invocation.invoke();
}
讲解权限控制的拦截器时,ServletActionContext.getRequest().getSession().getAttribute(“user”)方式,
还可以用ActionContext.getContext().getSession().get(“user”)方式判断用户是否登录,这个暂时不宜在这里引出讲解。
权限验证失败后的登录页面放在commons目录中,并且将登录的result视图配置为全局视图。最后要分析当前权限拦截器以及网上一些权限判断的网站的问题
用注解方式实现拦截器功能,可以看AnnotationWorkflowInterceptor的api帮助文档,或者看guides文档中讲解的注解配置方式。
l