拦截器的特点与作用
能够拦截进入Action的请求,做一些处理操作
例如:判断用户是否登录,判断用户角色是否正确,记录日志,等等
继承自com.opensymphony.xwork2.interceptor.Interceptor的子类为拦截器类.
package yzr.MyInterceptor;
import java.util.Map;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class MyInterceptor implements Interceptor {
@Override
public void destroy() {
}
@Override
public void init() {
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
ActionContext context = invocation.getInvocationContext();
Map<String, Object> sessionMap = context.getSession();
// 通过转发的时候可以通过request域获取参数值
String index = ServletActionContext.getRequest().getParameter("index");
System.out.println("Index=" + index);
String username = (String) sessionMap.get("username");
String password = (String) sessionMap.get("password");
if (username == null) {
return "notlogin";
}
if ("YZR".equalsIgnoreCase(username)
&& "123".equalsIgnoreCase(password)) {
return invocation.invoke();
} else {
return "errorlogin";
}
}
}
实现了拦截器类之后,还需要在struts.xml配置文件上加载,并且引用到需要被拦截的action中.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="login" extends="struts-default" namespace="/">
<interceptors>
<interceptor name="myInterceptor" class="yzr.MyInterceptor.MyInterceptor"></interceptor>
</interceptors>
<action name="IndexRequest"
class="yzr.MyInterceptor.IndexAction"
method="execute" >
<result name="success" type="dispatcher">
/Index/IndexResult.jsp
</result>
<result name="errorlogin" type="dispatcher">
/login/ErrorLogin.jsp
</result>
<result name="notlogin" type="dispatcher">
/login/notlogin.jsp
</result>
<interceptor-ref name="myInterceptor"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
<action name="loginRequest"
class="yzr.MyInterceptor.LoginAction"
method="loginMethod" >
<result name="success" type="dispatcher">
/Index/Index.jsp
</result>
<result name="input" type="dispatcher">
/login/login.jsp
</result>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
</package>
</struts>
struts.xml配置文件中,在不使用拦截器的条件下,默认会加载defaultStack,在这个默认的拦截器栈中定义了18个拦截器.
struts2-core-2.3.1.1.jar/struts-default.xml:
<interceptor-stack name="defaultStack">
<interceptor-ref name="exception"/>
<interceptor-ref name="alias"/>
<interceptor-ref name="servletConfig"/>
<interceptor-ref name="i18n"/>
<interceptor-ref name="prepare"/>
<interceptor-ref name="chain"/>
<interceptor-ref name="scopedModelDriven"/>
<interceptor-ref name="modelDriven"/>
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="checkbox"/>
<interceptor-ref name="multiselect"/>
<interceptor-ref name="staticParams"/>
<interceptor-ref name="actionMappingParams"/>
<interceptor-ref name="params">
<param name="excludeParams">dojo\..*,^struts\..*</param>
</interceptor-ref>
<interceptor-ref name="conversionError"/>
<interceptor-ref name="validation">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
<interceptor-ref name="debugging"/>
</interceptor-stack>
当假若加入自定义的拦截器之后,默认的defalutStack不会再加载了,我们需要手动加入对defaultStack的引用,这点需要注意.
在此实例中,通过配置文件可以看出,并没有为loginRequest的action标签添加MyInterceptor的引用,即访问此Action下的任意方法都不会被拦截器拦截,另外在IndexReuqest中添加了MyInterceptor的引用,所以在访问LoginAction之后,将username和password的数值保存到session中,当访问到达IndexRequest之前被MyInterceptor拦截时再拿出来做逻辑验证是否通过.
package yzr.MyInterceptor;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport {
private String username;
private String password;
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;
}
@Override
public String execute() throws Exception {
return SUCCESS;
}
public String loginMethod() throws Exception{
ActionContext.getContext().getSession().put("username", username);
ActionContext.getContext().getSession().put("password", password);
return "success";
}
}
当需要对action取消某个拦截器时,在struts.xml文件中,对应的action标签下去掉对应的拦截器的引用即可.
在引用的拦截器存在多个时,拦截器群执行的顺序是跟<interceptor-ref>引用顺序相关的,先引用的先执行,后引用的后执行.而且跟<interceptor>无关,什么时候定义的拦截器并不决定拦截器的执行顺序.
当需要使用的拦截器很多的时候,可以使用拦截器栈来表示:
<interceptors>
<interceptor name="myInterceptor" class="yzr.MyInterceptor.MyInterceptor"></interceptor>
<interceptor-stack name="myInterceptorStack">
<interceptor-ref name="myInterceptor"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!--
<interceptor-ref name="myInterceptor"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
-->
<interceptor-ref name="myInterceptorStack"></interceptor-ref>
源代码下载: 自定义拦截器案例源代码