什么是拦截器
拦截器就是AOP(Aspect-Oriented Programming)的一种实现(AOP是指用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作),Struts2中的拦截器只拦截Action类中的某些方法,不能拦截JSP。
Struts2拦截器采用责任链模式,在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链, 责任链每一个节点,都可以继续调用下一个节点,也可以阻止流程继续执行,在Struts2 中可以定义很多个拦截器,将多个拦截器按照特定顺序 组成拦截器栈 (顺序调用栈中的每一个拦截器 )。
默认的拦截器栈
Struts2的默认拦截器栈叫 defaultStack,定义在struts-default.xml中
拦截器和过滤器的区别
1)拦截器是基于JAVA反射机制的,而过滤器是基于函数回调的
2)过滤器依赖于Servlet容器,而拦截器不依赖于Servlet容器
3)拦截器只能对Action请求起作用(Action中的方法),而过滤器可以对几乎所有的请求起作用(CSS JSP JS)
自定义拦截器
编写拦截器,需要实现Interceptor接口,实现接口中的三个方法即init、destroy和intercept。
但是我们可以继承该接口的实现类,例如AbstractInterceptor,这样只需要重写intercept方法即可,查看其源码便可知晓:
/*
* Copyright 2002-2006,2009 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.opensymphony.xwork2.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
/**
* Provides default implementations of optional lifecycle methods
*/
public abstract class AbstractInterceptor implements Interceptor {
/**
* Does nothing
*/
public void init() {
}
/**
* Does nothing
*/
public void destroy() {
}
/**
* Override to handle interception
*/
public abstract String intercept(ActionInvocation invocation) throws Exception;
}
下面是创建拦截器的代码示例:
package blog.csdn.net.mchenys;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class MyIntercept extends AbstractInterceptor{
private static final long serialVersionUID = 1L;
@Override
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("Action方法执行之前...");
// 执行下一个拦截器
String result = invocation.invoke();
System.out.println("Action方法执行之后...");
return result;
}
}
配置拦截器
当拦截器定义好后,需要在struts.xml中进行拦截器的配置,配置一共有两种方式:
方式1:配置单个拦截器
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="default" namespace="/" extends="struts-default">
<!-- 定义拦截器 -->
<interceptors>
<!-- name:拦截器的名称 class:拦截器的全路径名称 -->
<interceptor name="DemoInterceptor" class="blog.youkuaiyun.com.mchenys.MyIntercept" />
</interceptors>
<!-- 使用拦截器 -->
<action name="regist1" class="blog.youkuaiyun.com.mchenys.Regist1Action">
<!-- 只要是引用自己的拦截器,默认栈的拦截器就不执行了,必须要手动引入默认栈 -->
<interceptor-ref name="DemoInterceptor" />
<!-- 还得引入默认的拦截器 -->
<interceptor-ref name="defaultStack" />
</action>
</package>
</struts>
方式2:配置拦截器栈
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="default" namespace="/" extends="struts-default">
<!-- 定义拦截器栈 -->
<interceptors>
<!-- name:拦截器的名称 class:拦截器的全路径名称 -->
<interceptor name="DemoInterceptor" class="blog.youkuaiyun.com.mchenys.MyIntercept" />
<!-- 定义拦截器栈 -->
<interceptor-stack name="myStack">
<!-- 引入自定义的拦截器 -->
<interceptor-ref name="DemoInterceptor" />
<!-- 引入默认的拦截器 -->
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<action name="regist2" class="blog.youkuaiyun.com.mchenys.Regist2Action" >
<!-- 引入拦截器栈 -->
<interceptor-ref name="myStack"/>
</action>
</package>
</struts>