日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

springboot拦截器拦截提示_Springboot拦截器使用及其底层源码剖析

發布時間:2025/5/22 javascript 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 springboot拦截器拦截提示_Springboot拦截器使用及其底层源码剖析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

 博主最近看了一下公司剛剛開發的微服務,準備入手從基本的過濾器以及攔截器開始剖析,以及在幫同學們分析一下上次的jetty過濾器源碼與本次Springboot中tomcat中過濾器的區別。正題開始,攔截器顧名思義是進行攔截請求的一系列操作。先給大家示例一下使用操作

1 @Configuration2 public class WebConfiguration implements WebMvcConfigurer {3 4 @Override5 public void addInterceptors(InterceptorRegistry registry) {6 registry.addInterceptor(new TstCfg());7 }8 }1 /** 2 * @title: TstCfg 3 * @Author junyu 4 * 舊巷里有一個穿著白襯衫笑起來如太陽般溫暖我的少年。 5 * 記憶里有一個穿著連衣裙哭起來如孩子般討人喜的女孩。 6 * 他說,哪年樹彎了腰,人見了老,桃花落了白發梢,他講的笑話她還會笑,那便是好。 7 * 她說,哪年國改了號,墳長了草,地府過了奈何橋,她回頭看時他還在瞧,就不算糟。 8 * @Date: 2020/7/29 11:53 9 * @Version 1.010 */11 public class TstCfg extends HandlerInterceptorAdapter {12 13 @Override14 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {15 System.out.println("前");16 return super.preHandle(request, response, handler);17 }18 19 @Override20 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {21 System.out.println("后");22 }23 24 @Override25 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {26 System.out.println("一直會出現");27 System.out.println(1/0);28 }29 }

 首先我們可能會想到,我們的攔截器是何時裝配到攔截器數組中

  其實就是在springboot啟動時執行doCreateBean時,進行調用創建的org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration會在這里放入進去所有實現了WebMvcConfigurer接口的類,一共有7個,其中就有我們自己實現了WebMvcConfigurer接口的WebConfiguration類,

  我們的寫的配置類WebConfiguration,繼承了WebMvcConfigurer并重寫了addInterceptors方法,所以我們的攔截器就在這時候裝配進去了。這次知道為什么我們寫的配置攔截器的配置示例需要繼承------WebMvcConfigurer,我們當然也可以去繼承已經實現了這個類的其他類,因為都可以去添加攔截器,博主親試過,所以就不貼圖了!

  好了,攔截器已經添加完了,那什么時候調用我們攔截器呢?一步一步腳印來,當瀏覽器請求我們地址的 時候,分以下幾步:

 第一步:tomcat容器首先會接受到請求,這里將會走DispatcherServlet,看到這個大家都熟悉了。

第二步:當然不會先走我們的攔截器了,我們的攔截器是在Springboot框架進行管理的,現在還在servlet,所以會先走到filter過濾器這一步,來貼圖:官方代碼太長,一屏截不下,前面有一個創建過濾器鏈的過程:等下次再給大家講一下jetty的過濾器鏈與tomcat的過濾器鏈的區別

ApplicationFilterChain filterChain = ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);

第三步:所以一旦連過濾器都沒通過的話,會直接return回去,不會再進行攔截器的調用。來貼代碼,過濾器通過后如何調用我們攔截器的

復制代碼 1 private void internalDoFilter(ServletRequest request, 2 ServletResponse response) 3 throws IOException, ServletException { 4 //這里將會調用所有過濾器鏈的過濾器,不做重點講解了,看看下面攔截器的調用 5 // Call the next filter if there is one 6 if (pos < n) { 7 ApplicationFilterConfig filterConfig = filters[pos++]; 8 try { 9 Filter filter = filterConfig.getFilter();10 11 if (request.isAsyncSupported() && "false".equalsIgnoreCase(12 filterConfig.getFilterDef().getAsyncSupported())) {13 request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR, Boolean.FALSE);14 }15 if( Globals.IS_SECURITY_ENABLED ) {16 final ServletRequest req = request;17 final ServletResponse res = response;18 Principal principal =19 ((HttpServletRequest) req).getUserPrincipal();20 21 Object[] args = new Object[]{req, res, this};22 SecurityUtil.doAsPrivilege ("doFilter", filter, classType, args, principal);23 } else {24 filter.doFilter(request, response, this);25 }26 } catch (IOException | ServletException | RuntimeException e) {27 throw e;28 } catch (Throwable e) {29 e = ExceptionUtils.unwrapInvocationTargetException(e);30 ExceptionUtils.handleThrowable(e);31 throw new ServletException(sm.getString("filterChain.filter"), e);32 }33 return;34 }35 36 // We fell off the end of the chain -- call the servlet instance37 try {38 if (ApplicationDispatcher.WRAP_SAME_OBJECT) {39 lastServicedRequest.set(request);40 lastServicedResponse.set(response);41 }42 43 if (request.isAsyncSupported() && !servletSupportsAsync) {44 request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR,45 Boolean.FALSE);46 }47 // Use potentially wrapped request from this point48 if ((request instanceof HttpServletRequest) &&49 (response instanceof HttpServletResponse) &&50 Globals.IS_SECURITY_ENABLED ) {51 final ServletRequest req = request;52 final ServletResponse res = response;53 Principal principal =54 ((HttpServletRequest) req).getUserPrincipal();55 Object[] args = new Object[]{req, res};56 SecurityUtil.doAsPrivilege("service",57 servlet,58 classTypeUsedInService,59 args,60 principal);61 } else {62 //過濾器終于完事了,現在終于開始正式調用我們的方法了,我們看看service方法做了什么吧!63 servlet.service(request, response);64 }65 } catch (IOException | ServletException | RuntimeException e) {66 throw e;67 } catch (Throwable e) {68 e = ExceptionUtils.unwrapInvocationTargetException(e);69 ExceptionUtils.handleThrowable(e);70 throw new ServletException(sm.getString("filterChain.servlet"), e);71 } finally {72 if (ApplicationDispatcher.WRAP_SAME_OBJECT) {73 lastServicedRequest.set(null);74 lastServicedResponse.set(null);75 }76 }77 }

其實最終它會調用到DispatcherServlet的doDispatch方法

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { 2 HttpServletRequest processedRequest = request; 3 HandlerExecutionChain mappedHandler = null; 4 boolean multipartRequestParsed = false; 5 6 WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); 7 8 try { 9 ModelAndView mv = null;10 Exception dispatchException = null;11 12 try {13 processedRequest = checkMultipart(request);14 multipartRequestParsed = (processedRequest != request);15 16 // Determine handler for the current request.17 mappedHandler = getHandler(processedRequest);18 if (mappedHandler == null) {19 noHandlerFound(processedRequest, response);20 return;21 }22 23 // Determine handler adapter for the current request.24 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());25 26 // Process last-modified header, if supported by the handler.27 String method = request.getMethod();28 boolean isGet = "GET".equals(method);29 if (isGet || "HEAD".equals(method)) {30 long lastModified = ha.getLastModified(request, mappedHandler.getHandler());31 if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {32 return;33 }34 }35 //所有攔截器開始在調用方法前攔截,如果你攔截器中返回false,則直接return不會再調用該方法!下面有源代碼36 if (!mappedHandler.applyPreHandle(processedRequest, response)) {37 return;38 }39 40 // Actually invoke the handler.41 //底層進行invoke反射,調用當前請求的方法,不用再往里面看了42 mv = ha.handle(processedRequest, response, mappedHandler.getHandler());43 44 if (asyncManager.isConcurrentHandlingStarted()) {45 return;46 }47 48 applyDefaultViewName(processedRequest, mv);49 //調用攔截器的postHandle,下面有源代碼50 mappedHandler.applyPostHandle(processedRequest, response, mv);51 }52 catch (Exception ex) {53 dispatchException = ex;54 }55 catch (Throwable err) {56 // As of 4.3, we're processing Errors thrown from handler methods as well,57 // making them available for @ExceptionHandler methods and other scenarios.58 dispatchException = new NestedServletException("Handler dispatch failed", err);59 }60 //該方法中多做了一些邏輯,其實最后也調用了triggerAfterCompletion方法,最終調用攔截器方法的afterCompletion方法61 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);62 }63 catch (Exception ex) {64 //所以不管是否出現異常,攔截器方法的afterCompletion方法是一定會調用的!65 triggerAfterCompletion(processedRequest, response, mappedHandler, ex);66 }67 catch (Throwable err) {68 //所以不管是否出現異常,攔截器方法的afterCompletion方法是一定會調用的!69 triggerAfterCompletion(processedRequest, response, mappedHandler,70 new NestedServletException("Handler processing failed", err));71 }72 finally {73 if (asyncManager.isConcurrentHandlingStarted()) {74 // Instead of postHandle and afterCompletion75 if (mappedHandler != null) {76 mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);77 }78 }79 else {80 // Clean up any resources used by a multipart request.81 if (multipartRequestParsed) {82 cleanupMultipart(processedRequest);83 }84 }85 }86 }

現在終于開始了我們攔截器的方法了,一個一個來:

1 boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception { 2 HandlerInterceptor[] interceptors = getInterceptors(); 3 if (!ObjectUtils.isEmpty(interceptors)) { 4 for (int i = 0; i < interceptors.length; i++) { 5 HandlerInterceptor interceptor = interceptors[i]; 6 //調用所有攔截器的preHandle方法 7 if (!interceptor.preHandle(request, response, this.handler)) { 8 //就算preHandle方法沒有通過,仍然會調用這個triggerAfterCompletion方法。 9 triggerAfterCompletion(request, response, null);10 return false;11 }12 this.interceptorIndex = i;13 }14 }15 return true;16 } 1 void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) 2 throws Exception { 3 4 HandlerInterceptor[] interceptors = getInterceptors(); 5 if (!ObjectUtils.isEmpty(interceptors)) { 6 for (int i = interceptors.length - 1; i >= 0; i--) { 7 HandlerInterceptor interceptor = interceptors[i]; 8 //調用攔截器的postHandle方法, 9 interceptor.postHandle(request, response, this.handler, mv);10 }11 }12 } 1 void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) 2 throws Exception { 3 4 HandlerInterceptor[] interceptors = getInterceptors(); 5 if (!ObjectUtils.isEmpty(interceptors)) { 6 for (int i = this.interceptorIndex; i >= 0; i--) { 7 HandlerInterceptor interceptor = interceptors[i]; 8 try { 9 //調用攔截器的afterCompletion方法,不管是否異常都會進行調用,但是如果該方法報異常,會被抓住。10 //不會影響程序正常運行,只會打印出來11 interceptor.afterCompletion(request, response, this.handler, ex);12 }13 catch (Throwable ex2) {14 logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);15 }16 }17 }18 }


下面這個就是打印了一下,但是不會影響我們的請求響應回去:

還是會正常響應回客戶端:

好了,到此攔截器的實現以及源碼分析流程到此結束,本來想給大家從Springboot的reflash方法開始解析攔截器,但是內容太多了,不僅跑題而且博主也一時半會給大家無法講解明白。

總結

以上是生活随笔為你收集整理的springboot拦截器拦截提示_Springboot拦截器使用及其底层源码剖析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日韩精品一卡 | 亚洲天堂精品一区 | 老鸭窝久久 | 男女瑟瑟网站 | 亚洲在线观看免费 | 国产交换配乱淫视频免费 | 成年人看的羞羞网站 | 一区二区久久久 | 女同亚洲精品一区二区三 | 中文av一区二区三区 | 欧洲精品码一区二区三区免费看 | 亚欧美视频 | 日韩视频一区二区三区四区 | 黄色69| 国产福利观看 | 成年人国产视频 | 日韩精品自拍偷拍 | 在线亚洲人成电影网站色www | 欧美不卡在线视频 | 欧美日韩一区二区区别是什么 | 久久日视频 | 国模吧无码一区二区三区 | 色呦呦在线观看视频 | 欧美一页 | 国产肥白大熟妇bbbb视频 | 三上悠亚人妻中文字幕在线 | 高清一区二区在线 | 91免费国产 | 激情久久五月天 | 久久黄色精品视频 | 私密spa按摩按到高潮 | 日韩网站免费观看高清 | 91嫩草欧美久久久九九九 | 亚洲精品一区二区三区蜜臀 | 三上悠亚ssⅰn939无码播放 | 男人天堂怡红院 | 天天躁日日躁bbbbb | 久久精品中文闷骚内射 | 特黄aaaaaaaaa毛片免费视频 | 国产一级片av | 久久久在线免费观看 | 午夜视频精品 | 亚洲欧洲成人 | 亚洲国产成人精品女人久久 | 国产日韩二区 | 欧美一区二区激情 | av毛片网站 | 亚洲自拍偷拍第一页 | 郑艳丽三级 | 国产精品一品二区三区的使用体验 | 99re视频在线 | 人人超碰在线 | 国产黄a三级三级三级看三级男男 | 亚洲国产精品99久久 | 精品国产乱码久久久久久鸭王1 | 亚洲午夜av在线 | 日本一二三区在线视频 | 影音先锋成人网 | 污污视频网站免费观看 | 日本久久视频 | 国产制服丝袜在线 | 国产aⅴ激情无码久久久无码 | 一级全黄男女免费大片 | 一个人在线观看免费视频www | 久久精品三级 | 午夜免费成人 | 无码毛片aaa在线 | 人妻奶水人妻系列 | 青春草在线视频观看 | 看片国产 | 超碰公开免费 | xxxxx日韩| 国产精品一区二区性色av | 成人午夜性视频 | 色综合久久久久久 | 欧美一级免费看 | 国内精品久久久久久久久久 | 偷看洗澡一二三区美女 | 成人一区二区免费视频 | 久插网| 97视频在线免费 | 成人片黄网站色大片免费毛片 | 经典av在线 | 亚洲高潮无码久久 | 精品一区二区欧美 | 农村少妇久久久久久久 | 日韩美女性生活 | 综合精品久久久 | 免费观看亚洲 | 射区导航 | 男女啪啪免费 | 看片久久| 国产免费一区二区视频 | 欧美三日本三级少妇三 | 五月天国产视频 | 国产精彩视频在线观看 | 嫩模一区二区三区 | 中文字幕第七页 | 国内自拍视频在线播放 |