zoukankan      html  css  js  c++  java
  • SpringMVC Interceptor 拦截器

    HandlerInterceptor 拦截器 

    (1)preHandle: 在执行controller处理之前执行,返回值为boolean ,返回值为true时接着执行postHandle和afterCompletion,如果我们返回false则中断执行

    (2)postHandle:在执行controller的处理后,在ModelAndView处理前执行

    (3)afterCompletion :在DispatchServlet执行完ModelAndView之后执行

    Source Code

     1 public interface HandlerInterceptor {
     2 
     3     /**
     4      * Intercept the execution of a handler. Called after HandlerMapping determined
     5      * an appropriate handler object, but before HandlerAdapter invokes the handler.
     6      * <p>DispatcherServlet processes a handler in an execution chain, consisting
     7      * of any number of interceptors, with the handler itself at the end.
     8      * With this method, each interceptor can decide to abort the execution chain,
     9      * typically sending an HTTP error or writing a custom response.
    10      * <p><strong>Note:</strong> special considerations apply for asynchronous
    11      * request processing. For more details see
    12      * {@link org.springframework.web.servlet.AsyncHandlerInterceptor}.
    13      * <p>The default implementation returns {@code true}.
    14      * @param request current HTTP request
    15      * @param response current HTTP response
    16      * @param handler chosen handler to execute, for type and/or instance evaluation
    17      * @return {@code true} if the execution chain should proceed with the
    18      * next interceptor or the handler itself. Else, DispatcherServlet assumes
    19      * that this interceptor has already dealt with the response itself.
    20      * @throws Exception in case of errors
    21      */
    22     default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    23             throws Exception {
    24 
    25         return true;
    26     }
    27 
    28     /**
    29      * Intercept the execution of a handler. Called after HandlerAdapter actually
    30      * invoked the handler, but before the DispatcherServlet renders the view.
    31      * Can expose additional model objects to the view via the given ModelAndView.
    32      * <p>DispatcherServlet processes a handler in an execution chain, consisting
    33      * of any number of interceptors, with the handler itself at the end.
    34      * With this method, each interceptor can post-process an execution,
    35      * getting applied in inverse order of the execution chain.
    36      * <p><strong>Note:</strong> special considerations apply for asynchronous
    37      * request processing. For more details see
    38      * {@link org.springframework.web.servlet.AsyncHandlerInterceptor}.
    39      * <p>The default implementation is empty.
    40      * @param request current HTTP request
    41      * @param response current HTTP response
    42      * @param handler handler (or {@link HandlerMethod}) that started asynchronous
    43      * execution, for type and/or instance examination
    44      * @param modelAndView the {@code ModelAndView} that the handler returned
    45      * (can also be {@code null})
    46      * @throws Exception in case of errors
    47      */
    48     default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
    49             @Nullable ModelAndView modelAndView) throws Exception {
    50     }
    51 
    52     /**
    53      * Callback after completion of request processing, that is, after rendering
    54      * the view. Will be called on any outcome of handler execution, thus allows
    55      * for proper resource cleanup.
    56      * <p>Note: Will only be called if this interceptor's {@code preHandle}
    57      * method has successfully completed and returned {@code true}!
    58      * <p>As with the {@code postHandle} method, the method will be invoked on each
    59      * interceptor in the chain in reverse order, so the first interceptor will be
    60      * the last to be invoked.
    61      * <p><strong>Note:</strong> special considerations apply for asynchronous
    62      * request processing. For more details see
    63      * {@link org.springframework.web.servlet.AsyncHandlerInterceptor}.
    64      * <p>The default implementation is empty.
    65      * @param request current HTTP request
    66      * @param response current HTTP response
    67      * @param handler handler (or {@link HandlerMethod}) that started asynchronous
    68      * execution, for type and/or instance examination
    69      * @param ex any exception thrown on handler execution, if any; this does not
    70      * include exceptions that have been handled through an exception resolver
    71      * @throws Exception in case of errors
    72      */
    73     default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
    74             @Nullable Exception ex) throws Exception {
    75     }
    76 
    77 }

    拦截器的功能

      从接口中的3个方法,可以看出,类似于AOP的操作,可以完成在请求到达方法之前,完成方法之后,以及视图解析之前被调用,例如在调用方法前做用户权限的验证,日志的记录等等。HandlerInterceptorAdapter 类实现了HandlerInterceptor接口,自定义的拦截器也可以通过继承该类来实现拦截。

    拦截器流程图

      拦截器的执行过程是有序的,多个interceptor可以在 xml中 进行配置。

    <mvc:interceptors>
            <bean class="com.interceptor.TestInterceptor" />
            <bean class="com.interceptor.DataInterceptor" /> 
    </mvc:interceptors>

    [2020-05-20 11:12:30,645] Artifact springmvcdemo:war exploded: Artifact is deployed successfully
    [2020-05-20 11:12:30,645] Artifact springmvcdemo:war exploded: Deploy took 2,023 milliseconds
    TestInterceptor preHandle....
    DataInterceptor preHandle....
    DataInterceptor postHandle....
    TestInterceptor postHandle....
    DataInterceptor afterCompletion....
    TestInterceptor afterCompletion....

    Single Interceptor

    Multi Interceptor

    interceptor1配置在interceptor2 之前

     

    Source Code 2

     1 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
     2         ……… 
     3         try {
     4             ……… 
     5             try {
     6                 ……… 
     7              mappedHandler = getHandler(processedRequest);
     8 
     9                 if (!mappedHandler.applyPreHandle(processedRequest, response)) {
    10                     return;
    11                 }
    12 
    13                 // Actually invoke the handler.
    14                 mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    15                 ……… 
    16                 mappedHandler.applyPostHandle(processedRequest, response, mv);
    17             }
    18             catch (Exception ex) {
    19                 ……… 
    20             }
    21             catch (Throwable err) {
    22                 ……… 
    23             }
    24             processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
    25         }
    26         catch (Exception ex) {
    27             triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
    28         }
    29         catch (Throwable err) {
    30             triggerAfterCompletion(processedRequest, response, mappedHandler,
    31                     new NestedServletException("Handler processing failed", err));
    32         }
    33          
    34     }

    篇幅有限以上只是拦截器的基本玩法,细节点并未涉及,有时间再写里面的 HandlerExecutionChain

  • 相关阅读:
    Java 学习 第二篇;面向对象 定义类的简单语法:
    Java 学习 第一篇
    Compiler Principles 语法分析
    未来智能机的发展趋势
    C语言IO操作总结
    python学习资料
    JavaScript 数组的创建
    JavaScript中的逗号运算符
    JavaScript本地对象 内置对象 宿主对象
    JavaScript的this用法
  • 原文地址:https://www.cnblogs.com/dreamtaker/p/12918362.html
Copyright © 2011-2022 走看看