SpringMVC5 的InterceptorHandler拦截器开发

1.拦载器介绍

SpringMVC拦截器(Interceptor)实现对每一个请求处理前后进行相关的业务处理,类似与servlet中的Filter。

SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor来实现的。

所有HandlerMapping实现都支持处理程序拦截器,当您希望将特定功能应用于特定请求时,这些拦截器非常有用——例如,校验检查会话,记录日志等。拦截器必须实现org.springframework.web的HandlerInterceptor接口。该接品有三种方法,可以提供足够的灵活性来进行各种预处理和后处理:

  • preHandle(..): 在实际的处理程序执行之前

  • postHandle(..): 在执行处理程序之后

  • afterCompletion(..): 完成后(..):完整的请求完成后

preHandle(..)方法返回一个布尔值。我们可以使用此方法中断或继续执行链的处理。当此方法返回true时,处理程序执行链将继续。当它返回false时,DispatcherServlet假设拦截器本身已经处理了请求(例如,呈现了一个适当的视图),并且不再继续执行执行链中的其他拦截器和实际的处理程序。

注意,postHandle在@ResponseBody和ResponseEntity方法中不太有用,因为响应是在HandlerAdapter中写入并提交的,而且是在postHandle之前。这意味着对响应进行任何更改都太晚了,比如添加额外的消息头。对于这样的场景,您可以实现ResponseBodyAdvice,或者将它声明为控制器通知bean,或者直接在RequestMappingHandlerAdapter上配置它

 

在SpringMVC中定义一个Interceptor非常简单,主要有两步操作;

1、HandlerInterceptor接口

2、注册拦截器

 

2.拦截器的工作原理

当收到请求时,DispatcherServlet将请求交给处理器映射(HandlerMapping),让它找出对应该请求的HandlerExecutionChain对象。

HandlerExecutionChain顾名思义就是一个执行链,它包含一个处理该请求的处理器(Handler),同时包括若干个对该请求实施拦截的拦截器(HandlerInterceptor).当HanderMapping返回HanderExceutionChain后,DispatcherServlet将请求交给定义在HandlerExcecutionChain中的拦截器和处理器一并处理。

HandlerExecutionChain是负责处理请求并返回ModelAndView的处理执行链,其结构如下;

 

想要开发一个拦截器,需要实现接口

public class SpringMvcInterceptor implements HandlerInterceptor{
​
    /**
     * 在请求到达Handler之前,先执行这个前置处理方法。当该方法返回false时,请求直接返回,不会传递到       * 链中下一个拦截器,更不会调用处理器链末端的Handler中,只有返回true时请求才向链中的下一个处理节      * 点传递。
     * SpringMvc中的拦截器是链式的,可以同时存在多个interceptor,springmvc会根据声明的前后顺序一个
     * 接一个的执行,且所有的interceptor中的preHandle方法都会在。
     */
    @Override
    public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2) throws Exception {
        // TODO Auto-generated method stub
        return true;
    }
​
    /**
     * 在业务处理器处理请求执行完成后,生成视图之前执行的动作 
     * 可在modelAndView中加入数据,比如当前时间
     */
    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
            Object arg2, ModelAndView arg3) throws Exception {
        // TODO Auto-generated method stub
​
    }
​
    /**
     * 在DispatcherServlet完全处理完请求后被调用,可用于清理资源、可记录操作日志等
     * 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion()
     */
    @Override
    public void afterCompletion(HttpServletRequest arg0,
            HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        // TODO Auto-generated method stub
​
    }
}

位于处理器链末端的是一个Handler,DispactherServlet通过HandlerAdapter适配器对Handler进行封装,并按统一的适配器接口对Handler处理方法进行调用。

3开发示例

1.创建 拦截器

自定义拦截器
public class TimeInterceptor implements HandlerInterceptor {

    //前置调用 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("preHandle 被调用:"+request.getRequestURL());
        System.out.println("当前时间是:"+new Date());
        request.setAttribute("startTime", System.currentTimeMillis());
        System.out.println(request.getRequestURI());
        if(request.getRequestURI().startsWith("/mvc329/user")) {
            System.out.println("user请求");
            response.sendRedirect(request.getContextPath()+"/index.jsp");
            return false;
        }else {
            return true;
        }
    }

    //后置调用
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle 被调用:"+request.getRequestURL());
        System.out.println("当前时间是:"+new Date());
        Long end=System.currentTimeMillis();
        Long start=(Long) request.getAttribute("startTime");
        System.out.println(handler+"调用 ,花费时间为:"+(end-start));
        if(modelAndView!=null) {
            System.out.println(handler+" viewName:"+(modelAndView.getViewName()));
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("afterCompletion 被调用:"+request.getRequestURL());
        System.out.println("当前时间是:"+new Date());
        Long end=System.currentTimeMillis();
        Long start=(Long) request.getAttribute("startTime");
        System.out.println(handler+"显示调用 ,花费时间为:"+(end-start));
    }
}

2注册拦截器

可以在SpringMVC.xml中配置多个拦截器,每个拦截器都可以指定一个匹配的映射路径,以限制拦截器的作用范围

<!-- springmvc.xml配置MVC拦截器 -->
    <mvc:interceptors>
     <!-- 使用bean定义一个interceptor,直接定义在mvc:interceptors根下面interceptor
        将拦截所有的请求-->
        <mvc:interceptor>
            <!-- 定义在mvc:interceptor下面的表示对特定的请求才进行拦截 -->
            <mvc:mapping path="/**"/>
            <mvc:exclude-mapping path="/book/**"/>
            <bean id="timerInterceptor" class="com.oracle.interceptor.TimeInterceptor">             </bean> 
        </mvc:interceptor>
    </mvc:interceptors>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值