struts2拦截器的使用与配置
拦截器和过滤器是类似的东西,它们的实现原理相同,但是却不是同一种东西,过滤器是web容器层面的,而拦截器是像struts2这样的控制器层面的。struts2本身就通过拦截器进行了诸如:参数注入,类型转换,…
当然我们也可以自定义拦截器,方法如下:
- 继承AbstractInterceptor,重写intercept方法
- 在struts的配置文件中配置拦截器
1.继承AbstractInterceptor,重写intercept方法
这里模拟了一个登陆验证的拦截器:通过判断session里面是否有userName这个属性检验用户是否登录过,来限制未登录用户非法访问系统页面。
package com.lyu.struts.sysmanage.interceptor;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class LoginInterceptor extends AbstractInterceptor {
private static final long serialVersionUID = 5774470426465392583L;
// 重写intercept方法,拦截器和action业务控制类一样,也是返回一个视图名,在配置文件中用result配置即可,后面详解
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("进入登录验证的拦截器");
String returnCode = "";
if (ServletActionContext.getRequest().getSession().
getAttribute("userName") != null) {
// 继续执行拦截器链里的下一个拦截器
returnCode = invocation.invoke();
} else {
returnCode = "index";
}
System.out.println("退出了登录验证的拦截器");
return returnCode;
}
}
2.在struts的配置文件中配置拦截器
1). 自定义一个包用来放置已经写好的拦截器,继承struts-default包,将abstract设置为true,里面不能放action,放了也没用,抽象类不能实例化,适合放拦截器。
<package name="mydefault-package" extends="struts-default" abstract="true">
<interceptors>
<interceptor name="loginInterceptor" class="com.lyu.struts.sysmanage.interceptor.LoginInterceptor" />
<interceptor-stack name="mydefaultStack">
<interceptor-ref name="loginInterceptor" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<!-- 默认使用的拦截器 -->
<default-interceptor-ref name="mydefaultStack" />
<!-- 如果拦截器找不到结果集,就会到全局的结果集中查找视图名 -->
<global-results>
<!-- 既能重定向到某个请求也能重定向到某个页面 -->
<result name="index" type="redirect">/index</result>
<!-- 在当前路径的基础上,重定向到某个请求(在视图名后追加".action"),而不是重定向到某个页面 -->
<!-- <result name="index" type="redirectAction">login</result> -->
</global-results>
</package>
2). 用interceptor标签配置拦截器,name随便起(语义化),class为你写好的拦截器的全限定性类名;interceptor-stack是拦截器栈(就是一组拦截器,这里因为还要实现参数注入,类型转换等功能所以还要引用struts2默认的拦截器栈defaultStack–详见struts2源码)。
<interceptors>
<interceptor name="loginInterceptor" class="com.lyu.struts.sysmanage.interceptor.LoginInterceptor" />
<interceptor-stack name="mydefaultStack">
<interceptor-ref name="loginInterceptor" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
3).配置一个默认的拦截器引用(可以是单个拦截器,也可以是拦截器栈),这样只要继承了该包就默认启用这个默认配置的拦截器,当然也可以在某个具体的action里面配置interceptor-ref。
<!-- 默认使用的拦截器 -->
<default-interceptor-ref name="mydefaultStack" />
像这样:
<action name="del" class="com.lyu.struts.sysmanage.action.UserAction" method="del">
<interceptor-ref name="testRef"></interceptor-ref>
<result name="delUser_suc">/WEB-INF/views/sysmanage/delUser_suc.jsp</result>
</action>
4).拦截器也要返回视图名,所以还要在相应的action里面配置result,像这样:
<action name="del" class="com.lyu.struts.sysmanage.action.UserAction" method="del">
<interceptor-ref name="testRef"></interceptor-ref>
<!-- 拦截器返回的视图名 -->
<result name="interceptroView" type="dispatcher">/main.jsp</result>
<result name="delUser_suc">/WEB-INF/views/sysmanage/delUser_suc.jsp</result>
</action>
当然也可以像配置默认拦截器引用一样,配置一个全局的返回结果:
<!-- 如果拦截器找不到结果集,就会到全局的结果集中查找视图名 -->
<global-results>
<!-- 既能重定向到某个请求也能重定向到某个页面 -->
<result name="index" type="redirect">/index</result>
<!-- 在当前路径的基础上,重定向到某个请求(在视图名后追加".action"),而不是重定向到某个页面 -->
<!-- <result name="index" type="redirectAction">login</result> -->
</global-results>
至此拦截器已经配置完毕,哪个包需要使用拦截器,继承刚才配置的拦截器包就可以了。
关于redirect和redirectAction的区别:redirect既能重定向到某个请求,也能重定向到某个具体的页面;而redirectAction只能重定向到某个请求,struts2会通过在视图名后面加“.action”的方式来实现,所以如果想使用这个方式,就不要在视图名后加“.action”,另外通过redirectAction方式进行的重定向只能在当前namespace的基础上进行,例如:当前包的namespace为“/sysmange”,redirectAction的视图名为“/index”,则重定向的请求为“/sysmanage//index.action”而不是“/index”,这里需要注意下。
下一篇: 浅谈Struts2拦截器的原理与实现