12 自定义拦截器
拦截器必须是无状态的,不要使用在API提供的ActionInvocation之外的任何东西。要求拦截器是无状态的原因是Struts 2不能保证为每一个请求或者action创建一个实例,所以如果拦截器带有状态,会引发并发问题。
创建步骤:
1. 实现接口com.opensymphony.xwork2.interceptor.Interceptor
或者继承类com.opensymphony.xwork2.interceptor.AbstractInterceptor
2. 通过<interceptor>
元素来定义拦截器
3. 通过<interceptor-ref>
元素来为action设置使用的拦截器
4. 自定拦截器重写public String intercept(ActionInvocation ai) throws Exception
方法
注意:如果为Action指定了一个拦截器,则系统默认的拦截器栈将会失去作用。为了继续使用默认拦截器,所以上面配置文件中手动引入了默认拦截器栈。
案例分析:登录权限验证。如果用户未登录访问action中的方法,则将其拦截提示没有操作权限;如果已经登录,则正常访问action。
(1) 用户所要操作的Action类:
package com.markliu.day05;
public class InterceptorTestAction {
private String permission;
public String getPermission() {
return permission;
}
public void setPermission(String permission) {
this.permission = permission;
}
public String execute() {
this.permission = "权限允许操作!";
return "nextstep";
}
}
(2) 对该action的操作进行拦截:
package com.markliu.day05.interceptor;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class PermissionInterceptor implements Interceptor {
private static final long serialVersionUID = -7561286728509952795L;
@Override
public void destroy() {
}
@Override
public void init() {
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
// 判断用户是否登录
Object user = ActionContext.getContext().getSession().get("user");
if (user != null) {
Object action = invocation.getAction();
System.out.println("所拦截的action:" + action);
System.out.println("所拦截的action的方法是否执行:" + invocation.isExecuted());
/**
* 唤醒下一步操作。 如果之后有其他的拦截器,则会调用下一个拦截器;
* 如果没有其他拦截器,则执行action的方法。
*/
String returnCode = invocation.invoke();
System.out.println("调用invoke后的返回String:" + returnCode);
return returnCode;
}
ActionContext.getContext().put("permission", "permission denyed!");
return "denyed";
}
}
(3)struts.xml文件配置,注册拦截器。
<package name="day05" namespace="/day05" extends="struts-default">
<interceptors >
<interceptor name="permissioncheck" class="com.markliu.day05.interceptor.PermissionInterceptor" />
<interceptor-stack name="permissionStack">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="permissioncheck" />
</interceptor-stack>
</interceptors>
<action name="interceptorTest" class="com.markliu.day05.InterceptorTestAction" method="execute">
<interceptor-ref name="permissionStack" />
<result name="nextstep">/pages/day05/nextstep.jsp</result>
<result name="denyed">/pages/day05/denyed.jsp</result>
</action>
</package>
(4)模拟登录的页面login.jsp
<%
session.setAttribute("user", "logined");
%>
处理流程分析:如果用户先访问login.jsp进行登录,session中保存user属性,再访问interceptorTest.action时,由于在struts.xml中对action进行连接器的注册,所以PermissionInterceptor会拦截用户的请求,在intercept方法中判断用户已经登录,则调用’invocation.invoke();’方法,如果还有其他的拦截器,则传递到下一个拦截器处理,如果没有则处理action。invocation.invoke();函数返回值为拦截action的方法execute的返回值,这样和result的name匹配,实现了未改变action的功能添加拦截器的功能。
如果用户未登录,则拦截器验证后没有调用invocation.invoke(),则不会执行action中的方法,而直接返回denyed,进入到denyed.jsp视图。
登录后运行后台输出:
所拦截的action:com.markliu.day05.InterceptorTestAction@250983a3
所拦截的action的方法是否执行:false
调用invoke后的返回String:nextstep
因为struts2中如文件上传,数据验证,封装请求参数到action等功能都是由系统默认的defaultStack中的拦截器实现的,所以我们定义的拦截器需要引用系统默认的defaultStack,这样应用才可以使用struts2框架提供的众多功能。
如果希望包下的所有action都使用自定义的拦截器,可以通过<default-interceptor-ref name=“permissionStack”/>
把拦截器定义为默认拦截器。注意:每个包只能指定一个默认拦截器。另外,一旦我们为该包中的某个action显式指定了某个拦截器,则默认拦截器不会起作用。
转载请注明出处:http://blog.csdn.net/mark_lq/article/details/49798365