Struts2是一个优秀的controller层框架,用Action类代替传统的Servlet,非常方便。
不仅如此,其实Struts2还有拦截器技术。主要目的是对部分不合法的数据进行处理
举个例子,比如,某系统登陆用户名必须要12位长度以下,传统Servlet来讲,我们得把这个限制条件用ifelse语句写到Servlet中,那么controller层的核心代码将会非常冗长,不够简洁!
有了拦截器,我们可以提前把这些不合法的数据处理掉,然后最后通过层层选拔,真正进入Action类执行代码的就是合法的数据了。好处多多啊
具体原理图如下:
可以看出,拦截器就好像我们现实生活中的考试一样,层层筛选。
现在写一个程序来测试下拦截器的使用:
登陆界面:提交一个action
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html>
<html>
<head>
<title>测试自定义拦截器</title>
</head>
<body>
<h1>用户登录</h1>
<a href="TestInterceptor.action">测试自定义拦截器</a>
</body>
</html>
在struts.xml文件中,我们接受到TestInterceptor这个action,然后我们按照要求执行相应类的login方法。当然,在这里不同的是,我们执行login方法之前,要先经过interceptor拦截器的筛选。
<?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.3.dtd">
<struts>
<package name="another" extends="struts-default">
<!-- 在action之前先定义自己的拦截器 -->
<interceptors>
<interceptor name="test1" class="testInterceptor.MyInterceptor"></interceptor>
</interceptors>
<action name="TestInterceptor" class="testInterceptor.LogAction" method="login">
<!-- 默认拦截器栈,必须加进来,否则struts程序无法正常运行 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<!-- 自定义的拦截器 -->
<interceptor-ref name="test1"></interceptor-ref>
<result name="fail">/fail.jsp</result>
<result name="success">/success.jsp</result>
</action>
</package>
</struts>
然后是我们的拦截器代码:
实现Interceptor接口,intercept方法中是我们要做的逻辑处理,筛掉不合理的数据。
这里我们简单模拟输出一下,观察拦截器的生命周期即可。
这里注意:
然后用ActionInvocation的对象ai,调用invoke方法,该方法的作用相当于提示程序继续做后面的拦截器筛选或者action类方法,简单来说,如果你的数据通过了验证,你就返回一个ai.invoke()即可。如果没有通过验证,就返回success或login这种状态信息,那么action类就不会做了。
package testInterceptor;
import org.eclipse.jdt.internal.compiler.ast.Invocation;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class MyInterceptor implements Interceptor{
@Override
public void destroy() {
System.out.println("拦截器销毁");
}
@Override
public void init() {
// TODO Auto-generated method stub
System.out.println("my拦截器创建");
}
/**
* 拦截器方法
*/
@Override
public String intercept(ActionInvocation ai) throws Exception {
System.out.println("正在执行my拦截器。。。");
return ai.invoke();
}
}
我的Action类:
package testInterceptor;
public class LogAction {
public String login() {
System.out.println("执行LogAction中的login方法。。。");
return "success";
}
}
【运行测试一下:】
通过结果,也验证了我们的判断。拦截器是在action类之前执行的,值得注意的是,拦截器的init方法是在tomcat启动的时候就调用了。
至此我们能初步理解拦截器的作用和意义了,如果要添加多个拦截器,可以这样修改:
<?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.3.dtd">
<struts>
<package name="another" extends="struts-default">
<!-- 先定义多个自己的拦截器 -->
<interceptors>
<interceptor name="test1" class="testInterceptor.MyInterceptor"></interceptor>
<interceptor name="test2" class="testInterceptor.AnotherInterceptor"></interceptor>
<!-- 再定义自己的拦截器栈,将多个拦截器装进去 -->
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="test1" />
<interceptor-ref name="test2" />
</interceptor-stack>
</interceptors>
<action name="TestInterceptor" class="testInterceptor.LogAction" method="login">
<interceptor-ref name="myStack"></interceptor-ref>
<result name="success">/success.jsp</result>
</action>
</package>
</struts>