拦截器的概念:
java里的拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action执行前阻止其执行,同时也提供了一种可以提取Action中可重用部分代码的方式。在AOP中,拦截器用于在某个方法或者字段被访问之前进行拦截,然后再之前或者之后加入某些操作。
自定义拦截器的步骤:
第一步:自定义一个实现了Interceptor接口的类,或者继承抽象类AbstractInterceptor。
第二步:在配置文件中注册定义的拦截器。
第三步:在需要使用Action中引用上述定义的拦截器,为了方便也可以将拦截器定义为默认的拦截器,这样在不加特殊说明的情况下,所有的Action都被这个拦截器拦截。
Spring拦截器:
抽象类HandlerInterceptorAdapter
我们如果在项目中使用了Spring框架,那么,我们可以直接继承HandlerInterceptorAdapter.java这个抽象类,来实现我们自己的拦截器。
HandlerInterceptorAdapter.java的源代码:
package org.springframework.web.servlet.handler; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; public abstract class HandlerInterceptorAdapter implements HandlerInterceptor{ // 在业务处理器处理请求之前被调用 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{ return true; } // 在业务处理器处理请求完成之后,生成视图之前执行 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception{ } // 在DispatcherServlet完全处理完请求之后被调用,可用于清理资源 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception{ } }
接下来我们看一下Spring框架实现的一个简单的拦截器UserRoleAuthorizationInterceptor,UserRoleAuthorizationInterceptor继承了抽象类HandlerInterceptorAdapter,实现了用户登录认证的拦截功能,如果当前用户没有通过认证,会报403错误。
package org.springframework.web.servlet.handler; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class UserRoleAuthorizationInterceptor extends HandlerInterceptorAdapter{ // 字符串数组,用来存放用户角色信息 private String[] authorizedRoles; public final void setAuthorizedRoles(String[] authorizedRoles){ this.authorizedRoles = authorizedRoles; } public final boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException{ if (this.authorizedRoles != null) { for (int i = 0; i < this.authorizedRoles.length; ++i) { if (request.isUserInRole(this.authorizedRoles[i])) { return true; } } } handleNotAuthorized(request, response, handler); return false; } protected void handleNotAuthorized(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException{ // 403表示资源不可用。服务器理解用户的请求,但是拒绝处理它,通常是由于权限的问题 response.sendError(403); } }
拦截器不需要在web.xml中配置。
过滤器与拦截器的区别:
过滤器可以简单的理解为“取你所想取”,过滤器关注的是web请求;拦截器可以简单的理解为“拒你所想拒”,拦截器关注的是方法调用,比如拦截敏感词汇。
1,拦截器是基于java反射机制来实现的,而过滤器是基于函数回调来实现的。(有人说,拦截器是基于动态代理来实现的)
2,拦截器不依赖servlet容器,过滤器依赖于servlet容器。
3,拦截器只对Action起作用,过滤器可以对所有请求起作用。
4,拦截器可以访问Action上下文和值栈中的对象,过滤器不能。
5,在Action的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时调用一次。