<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                當我們使用瀏覽器訪問一個不存在的地址時,SpringBoot 默認提供如下類似的404頁面。 ![](https://img.kancloud.cn/ff/74/ff74752c0415f56c3b527446d683551d_887x218.png) 當如 Android、IOS 等非瀏覽器客戶端訪問時,比如使用 [Postman](https://www.postman.com/downloads/) 客戶端軟件模擬請求一個不存在的頁面時響應的是json數據。 ![](https://img.kancloud.cn/6a/8f/6a8f461c15a18ef77e6a6ff249e3be58_1195x625.png) SpringBoot 的錯誤處理機制由 ErrorMvcAutoConfiguration 類管理,它的源碼如下,它注冊了下面4個錯誤處理組件。 ```java -----ErrorMvcAutoConfiguration----- @Bean @ConditionalOnMissingBean( value = {ErrorAttributes.class}, search = SearchStrategy.CURRENT ) // 組件1:DefaultErrorAttributes public DefaultErrorAttributes errorAttributes() { return new DefaultErrorAttributes(); } @Bean @ConditionalOnMissingBean( value = {ErrorController.class}, search = SearchStrategy.CURRENT ) // 組件2:BasicErrorController public BasicErrorController basicErrorController(ErrorAttributes errorAttributes, ObjectProvider<ErrorViewResolver> errorViewResolvers) { return new BasicErrorController(errorAttributes, this.serverProperties.getError(), (List)errorViewResolvers.orderedStream().collect(Collectors.toList())); } @Bean // 組件3:ErrorPageCustomizer public ErrorMvcAutoConfiguration.ErrorPageCustomizer errorPageCustomizer(DispatcherServletPath dispatcherServletPath) { return new ErrorMvcAutoConfiguration.ErrorPageCustomizer(this.serverProperties, dispatcherServletPath); } @Bean @ConditionalOnBean({DispatcherServlet.class}) @ConditionalOnMissingBean({ErrorViewResolver.class}) 組件4:DefaultErrorViewResolver DefaultErrorViewResolver conventionErrorViewResolver() { return new DefaultErrorViewResolver(this.applicationContext, this.resourceProperties); } ``` 這4個組件的調用步驟如下: 1. 當系統出現4xx或者5xx之類的錯誤 ,調用ErrorPageCustomizer來定制錯誤的響應規則,它會獲取系統默認的/error頁面; ```java -----ErrorMvcAutoConfiguration----- public void registerErrorPages(ErrorPageRegistry errorPageRegistry) { ErrorPage errorPage = new ErrorPage(this.dispatcherServletPath.getRelativePath(this.properties.getError().▲▲▲▲getPath()▲▲▲▲)); errorPageRegistry.addErrorPages(new ErrorPage[]{errorPage}); } -> -----ErrorProperties----- public class ErrorProperties { @Value("${error.path:/error}") private String path = "/error"; private boolean includeException; ``` 2. 接著調用BasicErrorController來處理這個/error頁面,BasicErrorController 會根據請求的頭部信息來判斷是來自瀏覽器的請求,還是客戶端的請求,決定應該響應一個頁面,還是json數據。 ![](https://img.kancloud.cn/e2/b6/e2b695e4261009b0193677a18b9f02b4_633x139.png) ![](https://img.kancloud.cn/08/a4/08a4e88b591b879b069d609da7aca105_734x343.png) ```java -----ErrorMvcAutoConfiguration----- @Bean @ConditionalOnMissingBean( value = {ErrorController.class}, search = SearchStrategy.CURRENT ) public ▲▲▲▲BasicErrorController▲▲▲▲ basicErrorController(ErrorAttributes errorAttributes, ObjectProvider<ErrorViewResolver> errorViewResolvers) { return new BasicErrorController(errorAttributes, this.serverProperties.getError(), (List)errorViewResolvers.orderedStream().collect(Collectors.toList())); } -> -----BasicErrorController----- @Controller // 如果沒有找到server.error.path,則采用errorp.path,如果還是沒有則最后采用/error錯誤配置 @RequestMapping({"${server.error.path:${error.path:/error}}"}) public class BasicErrorController extends AbstractErrorController { private final ErrorProperties errorProperties; @RequestMapping( produces = {"text/html"} ) // 當是瀏覽器訪問時,返回html public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) { HttpStatus status = this.getStatus(request); Map<String, Object> model = // 獲取模型數據 Collections.unmodifiableMap(▲▲▲▲this.getErrorAttributes(request, this.getErrorAttributeOptions(request, MediaType.TEXT_HTML))▲▲▲▲); response.setStatus(status.value()); // 去哪個頁面作為錯誤頁面 ModelAndView modelAndView = ▲▲▲▲this.resolveErrorView(request, response, status, model)▲▲▲▲; return modelAndView != null ? modelAndView : new ModelAndView("error", model); } // 當是非瀏覽器訪問時,返回json數據 @RequestMapping public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) { HttpStatus status = this.getStatus(request); if (status == HttpStatus.NO_CONTENT) { return new ResponseEntity(status); } else { Map<String, Object> body = this.getErrorAttributes(request, this.getErrorAttributeOptions(request, MediaType.ALL)); return new ResponseEntity(body, status); } } ``` 3. 接著DefaultErrorViewResolver起作用; 當是瀏覽器訪問時,響應的是html,DefaultErrorViewResolver解析應該響應哪個頁面; ```java -----ErrorMvcAutoConfiguration----- @Bean @ConditionalOnBean( { DispatcherServlet.class } ) @ConditionalOnMissingBean( { ErrorViewResolver.class } ) ▲▲▲▲DefaultErrorViewResolver▲▲▲▲ conventionErrorViewResolver() { return new DefaultErrorViewResolver(this.applicationContext, this.resourceProperties); } ->-----DefaultErrorViewResolver----- // 解析出是客戶端錯誤,還是服務端錯誤,客戶端錯誤為4xx,服務端錯誤為5xx,將它們存入Map中 static { Map<Series, String>views=new EnumMap(Series.class); views.put(Series.CLIENT_ERROR, "4xx"); views.put(Series.SERVER_ERROR, "5xx"); SERIES_VIEWS=Collections.unmodifiableMap(views); } // 返回對應的視圖 public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) { ModelAndView modelAndView=this.resolve(String.valueOf(status.value()), model); if (modelAndView==null && SERIES_VIEWS.containsKey(status.series())) { // 根據不同的狀態碼SERIES_VIEWS.get(status.series())解析出對應的視圖 modelAndView=this.resolve((String)SERIES_VIEWS.get(status.series()), model); } return modelAndView; } private ModelAndView resolve(String viewName, Map<String, Object> model) { // 將對應的視圖拼接為error/viewName,比如如果是404狀態碼,則為error/404.html String errorViewName="error/"+viewName; TemplateAvailabilityProvider provider=this.templateAvailabilityProviders.getProvider(errorViewName, this.applicationContext); // 如果模板引擎可用,而且解析的錯誤頁面可用,則用;如果不能用則用this.resolveResource(errorViewName, model)提供的錯誤頁面 return provider !=null ? new ModelAndView(errorViewName, model): this.resolveResource(errorViewName, model); } // 到靜態資源目錄下尋找可用的error頁面 private ModelAndView resolveResource(String viewName, Map<String, Object> model) { String[] var3=this.resourceProperties.getStaticLocations(); int var4=var3.length; for(int var5=0; var5 < var4; ++var5) { String location=var3[var5]; try { Resource resource=this.applicationContext.getResource(location); resource=resource.createRelative(viewName + ".html"); // 當靜態資源目錄下存在templates/error/404.html則用,不存在也是返回null if (resource.exists()) { return new ModelAndView(new DefaultErrorViewResolver.HtmlResourceView(resource), model); } } catch (Exception var8) {} } return null; } ``` 4. 最終由DefaultErrorAttributes來配置頁面的共享信息 ```java -----DefaultErrorAttributes----- errorAttributes.put("status", 999); // 狀態碼 errorAttributes.put("error", "None"); // 錯誤提示 errorAttributes.put("exception", error.getClass().getName()); // 異常對象 errorAttributes.put("message", message); // 消息 errorAttributes.put("errors", result.getAllErrors()); // jsr303數據校驗錯誤提示 errorAttributes.put("trace", stackTrace.toString()); errorAttributes.put("path", path); errorAttributes.put("timestamp", new Date()); ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看