什么是拦截器(Interceptor )?
拦截器,在AOP(Aspect-Oriented Programming)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。拦截是AOP的一种实现策略。
在WEB中,它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。同时也是提供了一种可以提取action中可重用的部分的方式。这是Webwork中给出的解释。
拦截器链(InterceptorChain,struts中叫做拦截器栈 InterceptorStack),就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,拦截器链中的拦截器就会
按其之前定义的顺序被调用。
什么是过滤器(filter)?
过滤器是一个程序,它先于与之相关的servlet或JSP页面运行在服务器上。过滤器可附加到一个或多个servlet或JSP页面上,并且可以检查进入这些资源的请求信息。在这
之后,过滤器可以作如下的选择:
1.以常规的方式调用资源(即,调用servlet或JSP页面)。
2.利用修改过的请求信息调用资源。
3.调用资源,但在发送响应到客户机前对其进行修改。
4.阻止该资源调用,将其转到其他的资源,返回一个特定的状态代码或生成替换输出。
两者的区别:
1.拦截器是基于java的反射机制的,而过滤器是基于函数回调。
2.拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
3.拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用,包括一些静态资源的访问。
4.拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
5.在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
不说了直接上代码:
拦截器:
public class UserInterceptor extends AbstractInterceptor {
private static final long serialVersionUID = 1L;
private Logger log=LoggerFactory.getLogger(UserInterceptor.class);
@Override
public String intercept(ActionInvocation invocation) throws Exception {
String result;
String methodName = invocation.getInvocationContext().getName();
log.info(methodName);
Object action = invocation.getAction();
if(action instanceof UserAction)
{
//如果是UserAction dosomething
UserAction useraction = (UserAction)action;
}
log.info("调用之前doSomething..........");
result=invocation.invoke();//调用被拦截的方法
log.info("调用之后doSomething..........");
return result;
}
}
struts2配置:
<?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" extends="struts-default" >
<interceptors>
<interceptor name="userInterceptor" class="lishuai.interceptor.UserInterceptor"></interceptor>
<interceptor-stack name="interceplist">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="userInterceptor"></interceptor-ref>
</interceptor-stack>
</interceptors>
<action name="user_*" class="lishuai.action.UserAction" method="{1}">
<interceptor-ref name="interceplist"></interceptor-ref>
</action>
</package>
</struts>
注:action配的是个拦截器栈,注意defaultStack是struts2的默认拦截器如果不配置则会覆盖掉struts2的默认拦截器,后果就是模型驱动(ModelDriven<T>)或者属性注入等,会
注入失败。
过滤器:
public class CharacterEncodingFilter implements Filter {
/*
* 编码方式
*/
private String characterEncoding;
/*
* 是否启用
*/
private boolean enabled;
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (enabled || characterEncoding != null) {
request.setCharacterEncoding(characterEncoding);
response.setCharacterEncoding(characterEncoding);
}
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig config) throws ServletException {
characterEncoding = config.getInitParameter("characterEncoding");
enabled = "true".equalsIgnoreCase(config.getInitParameter("enabled").trim());
}
}
web.xml配置:
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
注: 自己定义的过滤器要放到strtus2的过滤器之前的, 如果放在struts2过滤器之后,你自己的过滤器对action的过滤作用就废了,不会有效!除非你是访问jsp/html,切记。