一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Springboot錯誤頁面和錯誤信息定制操作

Springboot錯誤頁面和錯誤信息定制操作

2022-02-19 14:56YO_RUI Java教程

這篇文章主要介紹了Springboot錯誤頁面和錯誤信息定制操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

SpringBoot2.1.4錯誤處理機制

前面一片已經介紹了springboot錯誤處理的機制,其實從整個分析過程中我們已經大概知道如何定制了。

 

1、錯誤頁面自定義

springboot有個默認的錯誤頁面,但是開發時錯誤頁面肯定是自己定義的。那該如何定義?

在DefaultErrorViewResolver類中有下面幾個方法,

private ModelAndView resolve(String viewName, Map<String, Object> model) {
	// 定義視圖名,這里我們可以確定視圖名:error/錯誤碼,例如:error/404,
  String errorViewName = "error/" + viewName;
  // 這里結合上面的errorViewName,其實就是在template目錄下的error目錄進行查找
  // 我們默認情況下是沒有error目錄,這里的provide最終值為null,代碼較多就不一一展示,有興趣的可以跟下去
  TemplateAvailabilityProvider provider = this.templateAvailabilityProviders.getProvider(errorViewName, this.applicationContext);
  // 根據判定,這里會接著調用下面的resolveResource方法
  return provider != null ? new ModelAndView(errorViewName, model) : this.resolveResource(errorViewName, model);
}
private ModelAndView resolveResource(String viewName, Map<String, Object> model) {
	//  getStaticLocations()獲取的是靜態資源路徑:"classpath:/META-INF/resources/", "classpath:/resources/","classpath:/static/", "classpath:/public/"
  String[] var3 = this.resourceProperties.getStaticLocations();
  int var4 = var3.length;
	// 遍歷上面的4個靜態資源路徑
  for(int var5 = 0; var5 < var4; ++var5) {
      String location = var3[var5];
      try {
          Resource resource = this.applicationContext.getResource(location);
          // 創建resource對象,例如error/404.html
          resource = resource.createRelative(viewName + ".html");
          // 查找在對應靜態資源目錄下是否有上面的這個資源對象,有就創建視圖對象
          if (resource.exists()) {
              return new ModelAndView(new DefaultErrorViewResolver.HtmlResourceView(resource), model);
          }
      } catch (Exception var8) {
          ;
      }
  }
	// 都沒找到就返回null,默認情況下是不存在error目錄的,所以這里最終返回null
  return null;
}

在解析錯誤視圖界面時,會依次去這幾個目錄:template/classpath:/META-INF/resources/classpath:/resources/classpath:/static/classpath:/public/,在這些目錄下的error目錄里找文件名是錯誤狀態碼的頁面文件(404、500…)。

所以我們可以在這些目錄下創建error目錄,在里面創建HTML頁面,但是在template下面的頁面才能被thymeleaf模板引擎識別。

Springboot錯誤頁面和錯誤信息定制操作

現在再去訪問不存在路徑時效果如下,因為是404錯誤

Springboot錯誤頁面和錯誤信息定制操作

但是,錯誤狀態碼是很多的,不可能將所有的頁面全部寫出來,在DefaultErrorViewResolver類中有下面一段靜態代碼:

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);
}

向map中添加了兩個數據"4xx"、“5xx”,這個表示4開頭或者5開頭的錯誤,并且看到下面的:

public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
		// 按狀態碼精確查找
      ModelAndView modelAndView = this.resolve(String.valueOf(status.value()), model);
      // 若精確查找未找到再來模糊查找
      // status.series()方法可以自己看一下,就是在獲取錯誤碼的首位
      if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
          modelAndView = this.resolve((String)SERIES_VIEWS.get(status.series()), model);
      }
      return modelAndView;
  }

上面注釋寫的很清楚了,springboot首先按錯誤精確查找,若為找到再以錯誤碼首位模糊查找,所以我們也可以將錯誤頁面文件定義成 4xx.html 或者 5xx.html。

Springboot錯誤頁面和錯誤信息定制操作

 

2、錯誤數據

2.1 默認錯誤數據

頁面搞定了,那默認的錯誤數據有哪些呢?響應瀏覽器或者移動端錯誤請求的兩個方法中都同時用到了getErrorAttributes方法,這個方法就是用來獲取錯誤數據的。

  public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
      HttpStatus status = this.getStatus(request);
      Map<String, Object> model = Collections.unmodifiableMap(this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.TEXT_HTML)));
      response.setStatus(status.value());
      ModelAndView modelAndView = this.resolveErrorView(request, response, status, model);
      return modelAndView != null ? modelAndView : new ModelAndView("error", model);
  }
  @RequestMapping
  public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
      Map<String, Object> body = this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.ALL));
      HttpStatus status = this.getStatus(request);
      return new ResponseEntity(body, status);
  }

這個方法是屬于DefaultErrorAttributes類的,用來定義默認錯誤屬性。

  public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
      Map<String, Object> errorAttributes = new LinkedHashMap();
      errorAttributes.put("timestamp", new Date());
      this.addStatus(errorAttributes, webRequest);
      this.addErrorDetails(errorAttributes, webRequest, includeStackTrace);
      this.addPath(errorAttributes, webRequest);
      return errorAttributes;
  }

從這個方法及其里面調用其他幾個方法跟蹤可以知道有如下錯誤屬性:

  • timestamp:時間戳
  • status:錯誤碼
  • error:錯誤名
  • exception:異常類型
  • message:異常信息
  • trace:錯誤棧
  • path:錯誤路徑

Springboot錯誤頁面和錯誤信息定制操作

Springboot錯誤頁面和錯誤信息定制操作

2.2 自定義錯誤數據

下面模擬一個場景,發起一個請求,然后觸發一個自定義異常,自己添加一些錯誤信息,在頁面上顯示出來。 exception:

public class MyException extends RuntimeException {
  
  public MyException() {
      super("發生異常了");
  }
}

Controller:

@ResponseBody
@RequestMapping("/hello")
public String hello(@RequestParam("username") String username){
	// 當username值為aaa是拋出異常
  if(username.equals("aaa")){
      throw new MyException();
  }
  return "hello";
}

為了處理異常還要定義個異常處理器,關鍵點1:注意設置狀態碼的注釋

@ControllerAdvice
public class ExceptionController {
	  @ExceptionHandler(MyException.class)
	  public String f(HttpServletRequest request){
	      // 這里要更改狀態碼,前面訪問路徑是沒有問題的,所以狀態碼為200
	      // 若想要進入springboot錯誤處理流程,必須重設狀態碼
	      // 并且其key值為:javax.servlet.error.status_code
	      request.setAttribute("javax.servlet.error.status_code",500);
	      // 這里可以添加信息到request中,到后面的取出添加到map中
	      request.setAttribute("data","我的錯誤消息");
	      // 轉發到 /error請求,交給springboot處理
	      return "forward:/error";
	  }
}

關鍵點2,因為我們的錯誤信都是在DefaultErrorAttributes類中的getErrorAttributes方法中獲取的,若只是到上面步驟為止,那么在移動端將無法獲取到添加的data,所以為止同時使用瀏覽器和移動端,我們還必須創建一個類繼承DefaultErrorAttributes類,重寫getErrorAttributes方法,在這里才是真正的添加自定義的數據。

MyErrorAttribute

// 注意,給類必須添加到容器中,否則不生效
// 添加后將會覆蓋原有的DefaultErrorAttributes,采用我們自己的MyErrorAtribute
@Component
public class MyErrorAtribute extends DefaultErrorAttributes {
  @Override
  public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
      // 獲取包含錯誤信息的map
      Map<String, Object> map = super.getErrorAttributes(webRequest, includeStackTrace);
      // 添加自己的錯誤數據
      map.put("company","lr");
      //獲取轉發過來時添加的數據
      // 第二個參數表示在哪個域中獲取,0:request,1:session
      String data = (String)webRequest.getAttribute("data", 0);
      map.put("data",data); // 添加到map
      return map;
  }
}

然后我們測試,瀏覽器端:

Springboot錯誤頁面和錯誤信息定制操作

移動端:

Springboot錯誤頁面和錯誤信息定制操作

這樣,我們錯誤頁面,錯誤消息自定義,瀏覽器和移動端適配都解決了。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。

原文鏈接:https://blog.csdn.net/qq_34975710/article/details/90060014

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 特级淫片大乳女子高清视频 | 好男人资源免费播放在线观看 | 国产在亚洲线视频观看 | 校花小雪灌满了男人们的浓浆 | 6个老师的尿奴 | 午夜深情在线观看免费 | 国产综合欧美日韩视频一区 | 日本美女视频韩国视频网站免费 | 亚洲国产综合精品 | 粉嫩尤物在线456 | 亚洲伦理影院 | 国产亚洲精品精品国产亚洲综合 | 久草在线福利资站免费视频 | v视界影院_vsjla| 美女无内裤下部黄 | 日本xxxx18vr69 | 免费精品99久久国产综合精品 | 亚洲国产欧美日韩在线一区 | 国产第一页无线好源 | 91.prom在线观看国产 | 国产精品青青青高清在线密亚 | 欧美一级h| 午夜福利视频极品国产83 | 波多野结衣无码 | 国产精品自在线拍 | 91国内精品久久久久影院优播 | 黑人巨荃大战乌克兰美女 | 无遮免费网站在线入口 | 亚洲阿v天堂2018在线观看 | 免费视频专区一国产盗摄 | 日本黄色大片免费观看 | 亚洲羞羞裸色私人影院 | 问一问免费咨询 | 亚洲午夜精品久久久久久成年 | 日韩在线二区全免费 | 天天做天天爱天天综合网 | 国产精品馆 | 亚洲女同一区二区 | 精品久久久久久久久免费影院 | 婷婷综合久久中文字幕 | 日本在线看免费 |