从图中Struts2工作机制中可以看出来 Struts2框架的绝大部分功能是通过拦截器来完成的。当FilterDispatcher拦截到用户的请求之后 先问一下 ActionMapper有没有对应的Action 有的话 就调用ActionProxy处理。
Struts2内建的大量拦截器都是以name-class对的形式配置在struts-default.xml文件中的,其中name是拦截器的名字,class是该拦截器的实现类。
定义一个拦截类
定义一个拦截器 在struts.xml使用< interceptor >标签
<interceptor name="myInterceptor"class="org.easybooks.test.tools.MyInterceptor"></interceptor>
name是 拦截器的名字 class是该拦截器实现的类
通常情况下 一个Action要使用多个拦截器 可以把多个拦截器组成一个拦截器栈 使用标签
<!--定义-->
<interceptors>
<interceptor name="myInterceptor1" class="org.easybooks.test.tools.MyInterceptor1">
</interceptor>
<interceptor name="myInterceptor2" class="org.easybooks.test.tools.MyInterceptor2">
</interceptor>
<interceptor-stack name="interceptorStack">
<interceptor-ref name="myInterceptor1"></interceptor-ref>
<interceptor-ref name="myInterceptor2"></interceptor-ref>
</interceptor-stack>
</interceptors>
配置拦截器
定义好拦截器之后 记得配置 除了配置定义好的拦截器之外 还要记得配置默认拦截器 否则会报错(谨记 报错成狗了) 在Action定义好 result之后 使用< interceptor-ref > 标签即可。
<action name="main" class="org.easybooks.test.action.MainAction">
<result name="success">/main.jsp</result>
<result name="error">/error.jsp</result>
<result name="input">/login.jsp</result>
<!--一定记得要加默认拦截器-->
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="myInterceptor"></interceptor-ref>
<interceptor-ref name="interceptorStack"></interceptor-ref>
</action>
举例
拦截器的实现类 --里面的抛掷异常是我用来debug 看默认拦截器不配 会报NullPointerException
package org.easybooks.test.tools;
import com.opensymphony.xwork2.*;
import com.opensymphony.xwork2.interceptor.*;
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIConversion;
import org.apache.commons.lang3.ObjectUtils;
import org.easybooks.test.action.MainAction;
import org.easybooks.test.model.vo.UserTable;
public class MyInterceptor extends AbstractInterceptor{
//AbstractInterceptor 拦截器已实现 init() 和 destory()
public String intercept(ActionInvocation arg0) throws Exception{
try{
MainAction action = (MainAction)arg0.getAction();
if(action==null) System.out.println("NullAction");
UserTable userTable = action.getUser();
if(userTable==null) System.out.println("NullUserTable");
String username = userTable.getUsername();
if(username==null) System.out.println("NullUsername");
if(action.getUser().getUsername().equals("Administrator") || action.getUser().getUsername().equals("administrator")){
return Action.INPUT;
}
}catch(NullPointerException e){
e.printStackTrace();
MainAction action = (MainAction)arg0.getAction();
if(action==null) System.out.println("NullAction");
UserTable userTable = action.getUser();
if(userTable==null) System.out.println("NullUserTable");
String username = userTable.getUsername();
if(username==null) System.out.println("NullUsername");
return arg0.invoke();
}
return arg0.invoke();
}
}
这个 拦截器是看我输入的用户名是否为Administrator或者administrator 如果是的话 就返回到login页面
在看struts.xml配置
<?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="default" extends = "struts-default">
<!--定义-->
<interceptors>
<interceptor name="myInterceptor" class="org.easybooks.test.tools.MyInterceptor"></interceptor>
<interceptor-stack name="interceptorStack">
<interceptor-ref name="myInterceptor"></interceptor-ref>
</interceptor-stack>
</interceptors>
<action name="main" class="org.easybooks.test.action.MainAction">
<result name="success">/main.jsp</result>
<result name="error">/error.jsp</result>
<result name="input">/login.jsp</result>
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="myInterceptor"></interceptor-ref>
<interceptor-ref name="interceptorStack"></interceptor-ref>
</action>
</package>
<constant name="struts.i18n.encoding" value="gb2312"></constant>
</struts>
就像刚刚说的一样 使用< interceptor > 定义拦截器 在action中,在result后使用 < interceptor-ref >配置拦截器 即可。
看看效果
使用Administrator用户名登陆 因为拦截器的缘故 不会进到action之中 也就是没有数据库的调用 之后拦截器发现是Administrator 立刻返回INPUT 然后 返回login页面