<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring 攔截器流程及多個攔截器的順序

          共 4879字,需瀏覽 10分鐘

           ·

          2021-05-11 00:29

          fb99701349379a4ffb1eb7470f148017.webp

          ? ? ? ?攔截器是 Spring MVC 中的組件,它可以在進入請求方法前做一些操作,也可以在請求方法后和渲染視圖后做一些事情。


          攔截器的定義

          ? ? ? ?SpringMVC 的攔截器只需要實現(xiàn) HandlerInterceptor 接口,并進行配置即可。HandlerInterceptor 接口的定義如下:

          public interface HandlerInterceptor {    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        return true;    }
          default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { }
          default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { }}

          ? ? ? ?在 HandlerInterceptor 中共有三個方法,每個方法的含義如下:

          preHandler:進入請求方法之前執(zhí)行;

          postHandler:請求方法執(zhí)行完成之后執(zhí)行;

          afterCompletion:視圖渲染后執(zhí)行。


          攔截器的執(zhí)行流程

          ? ? ? ??在 preHandle 方法中,它的返回值是 boolean 類型的,它的返回值影響著請求方法,以及 postHandle 和 afterCompletion 的執(zhí)行。具體如下。

          fad590bfc9415e11070bab3f88a0a05e.webp

          ? ? ? ? 也就是說,在 preHandle 中如果返回 false,那么后續(xù)的流程將不被執(zhí)行,這可能也是攔截器命名的由來。


          測試攔截器

          ? ? ? ?寫一個簡單攔截器,代碼如下:

          @Slf4jpublic class TestInterceptor implements HandlerInterceptor {    @Override    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {        log.info("preHandler");        return true;    }
          @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { log.info("postHandler"); }
          @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { log.info("afterCompletion"); }}

          ? ? ? ? 創(chuàng)建了一個 TestInterceptor 的監(jiān)聽器類,它實現(xiàn)了 HandlerInterceptor 的所有接口。寫完 TestInterceptor 還需要進行注冊。代碼如下:

          @Configurationpublic class InterceptorConfig implements WebMvcConfigurer {
          @Override public void addInterceptors(InterceptorRegistry registry) {????????registry.addInterceptor(testInterceptor()); }

          ? ?? ? ?再來寫一個簡單的請求方法,代碼如下:

          @GetMapping("test")public String test(){    return "test";}

          ? ? ? ?來啟動我們的項目,并進行訪問,控制臺的輸出如下:

          2021-05-05 16:02:08.110  INFO 88509 --- [nio-8081-exec-6] com.example.demo.TestInterceptor         : preHandler2021-05-05 16:02:08.111  INFO 88509 --- [nio-8081-exec-6] com.example.demo.TestInterceptor         : postHandler2021-05-05 16:02:08.111  INFO 88509 --- [nio-8081-exec-6] com.example.demo.TestInterceptor         : afterCompletion


          多個攔截器的執(zhí)行順序

          ? ? ? ??我們來寫多個相同的監(jiān)聽器,分別是 TestInterceptor、TestInterceptor2 和 TestInterceptor3。然后我們進行注冊,注冊代碼如下:

          @Overridepublic void addInterceptors(InterceptorRegistry registry) {    registry.addInterceptor(testInterceptor());    registry.addInterceptor(testInterceptor2());    registry.addInterceptor(testInterceptor3());}

          ? ? ? ? 請求我們的方法,輸出如下:

          2021-05-05 16:09:57.735  INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor         : preHandler2021-05-05 16:09:57.736  INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2        : preHandler22021-05-05 16:09:57.736  INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor3        : preHandler32021-05-05 16:09:57.755  INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor3        : postHandler32021-05-05 16:09:57.755  INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2        : postHandler22021-05-05 16:09:57.755  INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor         : postHandler2021-05-05 16:09:57.755  INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor3        : afterCompletion32021-05-05 16:09:57.755  INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2        : afterCompletion22021-05-05 16:09:57.755  INFO 88572 --- [nio-8081-exec-1] com.example.demo.TestInterceptor         : afterCompletion

          ? ? ? ? 注意觀察輸出的順序,preHandle 方法是按注冊順序進行執(zhí)行的,而 postHandle 和 afterCompletion 跟注冊順序是相反的。


          讓 preHandle 進行攔截

          ? ? ? ? 我們讓 TestInterceptor2 的 preHandle 返回值為 false,然后查看一下輸出內(nèi)容。

          2021-05-05 16:14:00.997  INFO 88582 --- [nio-8081-exec-1] com.example.demo.TestInterceptor         : preHandler2021-05-05 16:14:00.998  INFO 88582 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2        : preHandler22021-05-05 16:14:00.998  INFO 88582 --- [nio-8081-exec-1] com.example.demo.TestInterceptor         : afterCompletion

          ? ? ? ??可以看到,TestInterceptor2 的 preHandle 的返回值為 false 以后,相當于在 TestInterceptor2 的 preHandle 后續(xù)流程則不再繼續(xù)執(zhí)行了。

          ? ? ? ? 我們調(diào)整一下注冊的順序,代碼如下:

          @Overridepublic void addInterceptors(InterceptorRegistry registry) {    registry.addInterceptor(testInterceptor2());    registry.addInterceptor(testInterceptor());    registry.addInterceptor(testInterceptor3());}

          ? ? ? ?修改順序后的輸出如下:

          2021-05-05 16:17:23.956  INFO 88589 --- [nio-8081-exec-1] com.example.demo.TestInterceptor2        : preHandler2

          ? ? ? ?可以看到它后面的流程都被攔截了,沒有機會執(zhí)行了。


          總結(jié)

          ? ? ? ? 攔截器是使用一個 List 進行保存,我們可以在項目中添加多個攔截器來完成不同的功能,比如可以進行 Token 的驗證,權(quán)限的獲取等。我們可以放到不同的攔截器中來進行相關(guān)的操作。


          瀏覽 61
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  香蕉福利在线观看 | 国产精品又污又黄又爽污污 | 波多野结衣av一区二区全免费观看 | 欧美一级精品免费 | 精品日韩人妻无码一区二区三区四区 |