首页
学习
活动
专区
圈层
工具
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Spring的三大器之拦截器

拦截器的概念

Java 里的拦截器是动态拦截 action 调用的对象。它提供了一种机制可以使开发者可以定义在一个action 执行的前后执行的代码,也可以在一个action 执行前阻止其执行,同时也提供了一种可以提取action 中可重用部分的方式。在AOP(Aspect-OrientedProgramming)中拦截器用于在某个方法或字段被访问之前进行拦截,然后在之前或之后加入某些操作。

拦截器的原理

大部分时候,拦截器方法都是通过代理的方式来调用的。Struts2的拦截器实现相对简单。当请求到达Struts2的ServletDispatcher时,Struts2 会查找配置文件,并根据配置实例化相对的拦截器对象,然后串成一个列表(List),最后一个一个的调用列表中的拦截器。Struts2的拦截器是可 插拔的,拦截器是AOP的一个实现。Struts2拦截器栈就是将拦截器按一定的顺序连接成一条链。在访问被拦截的方法或者字段时,Struts2拦截器链 中的拦截器就会按照之前定义的顺序进行调用。

自定义拦截器的步骤 第一步:自定义一个实现了Interceptor接口的类,或者继承抽象类AbstractInterceptor。 第二步:在配置文件中注册定义的拦截器。 第三步:在需要使用Action中引用上述定义的拦截器,为了方便也可以将拦截器定义为默认的拦截器,这样在不加特殊说明的情况下,所有的 Action都被这个拦截器拦截。

过滤器与拦截器的区别 过滤器可以简单的理解为“取你所想取”,过滤器关注的是web请求;拦截器可以简单的理解为“拒你所想拒”,拦截器关注的是方法调用,比如拦截 敏感词汇。 1,拦截器是基于java反射机制来实现的,而过滤器是基于函数回调来实现的。(有人说,拦截器是基于动态代理来实现的) 2,拦截器不依赖servlet容器,过滤器依赖于servlet容器。 3,拦截器只对Action起作用,过滤器可以对所有请求起作用。 4,拦截器可以访问Action上下文和值栈中的对象,过滤器不能。 5,在Action的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时调用一次。

看下HandlerInterceptor

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, HttpServletResponseresponse, 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框架提供的HandlerInterceptorAdapter抽过类,来实现一个自定义的拦截器。

代码语言:javascript
复制
首先再配置文件中配置拦截器:
代码语言:javascript
复制
<mvc:interceptors>
    <bean class="com.test.core.interceptor.LoginInterceptor"/>
</mvc:interceptors>
代码语言:javascript
复制
public class LoginInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String str = request.getRequestURI();
        String uri = str.split("\\?")[0];
        /**
         * 接口不拦截
         */
        if (uri.startsWith("/service/")) {
            return super.preHandle(request, response, handler);
        }
        //首页 登录 验证码 js css gif png jpg 不拦截
        if (uri.endsWith("login") || 
代码语言:javascript
复制
uri.endsWith("registVerfyCode") ||    
代码语言:javascript
复制
 uri.equals("/errorBrowser") ||
            uri.endsWith(".js") || 
代码语言:javascript
复制
uri.endsWith(".css") || 
代码语言:javascript
复制
uri.endsWith(".gif") || 
代码语言:javascript
复制
uri.endsWith(".png") || 
代码语言:javascript
复制
uri.endsWith(".jpg") || 
代码语言:javascript
复制
uri.endsWith(".ico") ||) {
            return super.preHandle(request, response, handler);
        } else {
            //获取session
            HttpSession session = request.getSession();
            if (null != session.getAttribute(SessionKeysConstant.LOGIN_USER)) {
                return super.preHandle(request, response, handler);
            } else {
                if (request.getHeader("x-requested-with") != null && request.getHeader("x-    
代码语言:javascript
复制
requested-with").equalsIgnoreCase("XMLHttpRequest")) { //如果是ajax请求响应头会有,x-requested-withresponse.setHeader("sessionstatus", "timeout");//在响应头设置session状态
代码语言:javascript
复制
} else {
      response.sendRedirect("/login");
      }
代码语言:javascript
复制
return false;
    }
 }
代码语言:javascript
复制
}
代码语言:javascript
复制
@Override
代码语言:javascript
复制
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        super.postHandle(request, response, handler, modelAndView);
    }
代码语言:javascript
复制
@Override
代码语言:javascript
复制
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        super.afterCompletion(request, response, handler, ex);
    }
@Override
代码语言:javascript
复制
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        super.afterConcurrentHandlingStarted(request, response, handler);
    }
}

拦截器实现的两种方式:

第一种:继承HandlerInterceptor

第二种:继承WebRequestInterceptor

这两种的区别:对于prehandler而言,第一种有返回值,能终止请求,第二种没有返回值,不能终止请求。

下一篇
举报
领券