1. Interceptor拦截器
1.1. 拦截器简介
拦截器是struts2框架的核心,包括解析请求的参数,将请求参数赋值给action的属性,执行数据校验,文件上传等都是通过拦截器是实现的。Struts2设计的灵巧性更大得益于拦截器的设计,当需要扩展struts2功能时,只要提供相应的拦截器,并将其配置在struts2容器中就行了。若不需要这个功能,也只要取消其对应的拦截器配置就OK了。
Struts2内建了大量的拦截器,这些拦截器以name-class对的形式配置在struts-default.xml文件中,其中name就是拦截器的名字,也是访问调用拦截器的唯一性标识,class则指定了其实现类。如果我们定义的package继承了struts2默认的struts-default包,则可以自由使用其中定义的拦截器,否则就得自定义了。
接下来简要的介绍一下一些拦截器的功能。
1.2. 自定义拦截器
首先请大家先了解一下下面的几个类或接口。
Interceptor
AbstractInterceptor
MethodFilterInterceptor
类型一:
public class TestInterceptor extends AbstractInterceptor
{
@Override
public String intercept(ActionInvocation invocation)
throws Exception
{
System.out.println("拦截器开始");
//查询API,了解一下invoke这个方法
String result = invocation.invoke();
System.out.println("拦截结束");
return result;
}
}
注:每个action在执行时都会调用拦截器,action执行结束后再调用一次。
类型二:
public class MethodInterceptor extends MethodFilterInterceptor
{
@Override
protected String doIntercept(ActionInvocation invocation)
throws Exception
{
System.out.println("拦截器开始");
//查询API,了解一下invoke这个方法
String result = invocation.invoke();
System.out.println("拦截结束");
return result;
}
}
注:以上这两种创建的拦截器都需要在配置文件中进行配置后才能使用。
<interceptors>
<interceptor
name="自定义名称" class="com.sun.TestInterceptor" />
<interceptor>
name="自定义名称" class="com.sun.MethodInterceptor">
//配置不需要拦截的方法
<param name="excludeMethods">方法名</param>
</interceptor>
</interceptors>
同样的,也可以设定需要拦截的方法--includeMethods,多个不同的方法之间用逗号隔开:
<interceptor>
name="自定义名称" class="com.sun.MethodInterceptor">
<param name="includeMethods">方法1,方法2,方法3</param>
</interceptor>
全局与局部发生冲突时,局部设置覆盖全局设置,includeMethods大于excludeMethods。
1.3. 页面刷新
当后台设置了执行延迟或等待中,通过设置一个拦截器,给用户一个好的用户体验。
可以控制页面定时刷新:
一. 在页面头部上
<% String path = request.getContext();
Response.setHeader("refresh","3;url=wait.jsp");
二. 在页面头部中
<meta http-equiv="refresh" content="3",url=wait.jsp">
Wait.jsp指代当前页面或是需要访问的action。
配置拦截器【wait】
在指定的action中引用拦截器
<interceptor-ref name="execAndWait" />
//因为defaultStack中没有,所有得手动引入。
<interceptor-ref name="defaultStack" />
//因为手动引入了一个拦截器,同时还需要一些其他的拦截器,所以必须引用该拦截器
<result name="wait">wait.jsp</result>
//wait为系统自带常量,不可更改,给系统一个视图,用于显示。
注意:execAndWait必须在所有拦截器之后,否则会出错。
页面从后台action跳转过来如果很快,就没有必要设置wait拦截器了,可以进行判断选择性拦截。
<interceptor-ref name="execAndWait">
<param name="delay">1000</param>
</interceptor-ref>
等待一秒后再显示提示页面,在1秒内如果等待结束,则显示成功页面
1.4. 令牌【token】
一. 前台
在正常的表单提交中多添加一个标签
<s:token></s:token>
二. 配置文件
在指定的需要访问的action中添加以下拦截器
<interceptor-ref name="token" />
<result name="invalid.token">指定的指向</result>
<interceptor-ref name="defaultStack" />
//只要手动引入了一个拦截器,那么就需要引用默认的拦截器。
解释:
第一次访问的到页面时,服务器记录了令牌的随机数作为登录的sessionId,第一次提交时,比较这两者是否一致,一致则进行数据提交或是页面跳转,同时清空这个sessionId,再次刷新时,两者当然不会一致,拦截器会返回一个Invalid.token,进而根据用户在配置文件中的信息区进行处理。
除了根据Invalid.token去执行不同的页面外,还有一种始终指向成功页面的方法,需要在配置文件中配置如下:
<interceptor-ref name="tokenSession" />
//服务器端存在的信息指向,始终返回数据提交后的页面
<interceptor-ref name="defaultStack" />