前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring的三大器之拦截器

Spring的三大器之拦截器

作者头像
一觉睡到小时候
发布2019-07-04 16:44:51
7650
发布2019-07-04 16:44:51
举报
文章被收录于专栏:国产程序员国产程序员

拦截器的概念

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而言,第一种有返回值,能终止请求,第二种没有返回值,不能终止请求。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-06-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 国产程序员 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档