真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

如何實(shí)現(xiàn)Springboot錯(cuò)誤處理機(jī)制

小編這次要給大家分享的是如何實(shí)現(xiàn)Springboot錯(cuò)誤處理機(jī)制,文章內(nèi)容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。

創(chuàng)新互聯(lián)公司服務(wù)項(xiàng)目包括舟曲網(wǎng)站建設(shè)、舟曲網(wǎng)站制作、舟曲網(wǎng)頁制作以及舟曲網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,舟曲網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到舟曲省份的部分城市,未來相信會繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

1.默認(rèn)的錯(cuò)誤機(jī)制

默認(rèn)效果

①在瀏覽器中訪問不存在的請求時(shí),springboot默認(rèn)返回一個(gè)空白頁面

如何實(shí)現(xiàn)Springboot錯(cuò)誤處理機(jī)制

瀏覽器的請求頭

如何實(shí)現(xiàn)Springboot錯(cuò)誤處理機(jī)制

②客戶端訪問時(shí),返回json數(shù)據(jù)

{
  "timestamp": "2020-03-24T02:49:56.572+0000",
  "status": 404,
  "error": "Not Found",
  "message": "No message available",
  "path": "/"
}

客戶端訪問的請求頭

如何實(shí)現(xiàn)Springboot錯(cuò)誤處理機(jī)制

原理

可以參照 ErrorMvcAutoConfiguration 錯(cuò)誤處理的自動配置

給容器中添加了以下組件

1.DefaultErrorAttributes

public Map getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
  Map errorAttributes = new LinkedHashMap();
  errorAttributes.put("timestamp", new Date());
  this.addStatus(errorAttributes, webRequest);
  this.addErrorDetails(errorAttributes, webRequest, includeStackTrace);
  this.addPath(errorAttributes, webRequest);
  return errorAttributes;
}
@RequestMapping(
    produces = {"text/html"}
  )
  public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
    HttpStatus status = this.getStatus(request);
    //處理頁面的請求返回給前臺數(shù)據(jù) model 的獲取 ,調(diào)用
    Map 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);
  }
 
 
 
//調(diào)用 AbstractErrorController#getErrorAttributes
  protected Map getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) {
    WebRequest webRequest = new ServletWebRequest(request);
    return this.errorAttributes.getErrorAttributes(webRequest, includeStackTrace);
  }
 
 
 
最終調(diào)用DefaultErrorAttributes#getErrorAttributes
  public Map getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {

2.BasicErrorController : 處理默認(rèn)的 /error 請求

@Controller
@RequestMapping({"${server.error.path:${error.path:/error}}"}) 
public class BasicErrorController extends AbstractErrorController {
  private final ErrorProperties errorProperties;
public String getErrorPath() {
  return this.errorProperties.getPath();
}

@RequestMapping(
  produces = {"text/html"}  //產(chǎn)生html類型的數(shù)據(jù),瀏覽器發(fā)送的請求來到這個(gè)方法處理
)
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
  //獲取狀態(tài)碼
  HttpStatus status = this.getStatus(request);
  //獲取模型數(shù)據(jù)
  Map model = Collections.unmodifiableMap(this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.TEXT_HTML)));
  response.setStatus(status.value());
  //去哪個(gè)頁面作為錯(cuò)誤頁面,包括頁面地址和內(nèi)容
  ModelAndView modelAndView = this.resolveErrorView(request, response, status, model);
  return modelAndView != null ? modelAndView : new ModelAndView("error", model);
}

@RequestMapping //產(chǎn)生json類型的數(shù)據(jù), 其他客戶端發(fā)送的請求來到這個(gè)方法處理
public ResponseEntity> error(HttpServletRequest request) {
  HttpStatus status = this.getStatus(request);
  if (status == HttpStatus.NO_CONTENT) {
    return new ResponseEntity(status);
  } else {
    Map body = this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.ALL));
    return new ResponseEntity(body, status);
  }
}

                 3.ErrorPageCustomizer

public class ErrorProperties {
  @Value("${error.path:/error}")
  private String path = "/error";  //系統(tǒng)出現(xiàn)錯(cuò)誤請求之后來到 /error 請求進(jìn)行處理 ,(類似于以前 web.xml 中注冊的錯(cuò)誤頁面規(guī)則)

4.DefaultErrorViewResolver

public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map model) {
    ModelAndView modelAndView = this.resolve(String.valueOf(status.value()), model);
    if (modelAndView == null && SERIES_VIEWS.containsKey(status.series())) {
      modelAndView = this.resolve((String)SERIES_VIEWS.get(status.series()), model);
    }
 
    return modelAndView;
  }
 
  private ModelAndView resolve(String viewName, Map model) {    //默認(rèn) springboot 可以找到這個(gè)頁面 error/404
    String errorViewName = "error/" + viewName;    //模板引擎可以解析這個(gè)頁面地址就用模板引擎解析
    TemplateAvailabilityProvider provider = this.templateAvailabilityProviders.getProvider(errorViewName, this.applicationContext);    //模板引擎可用的情況下就返回到 errorViewName 指定的視圖地址
    return provider != null ? new ModelAndView(errorViewName, model) : this.resolveResource(errorViewName, model);
  }
   //模板引擎不可用就在靜態(tài)資源文件夾里面找 errorViewName 對應(yīng)的頁面  error/404.html
  private ModelAndView resolveResource(String viewName, Map 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");          //如果靜態(tài)資源文件中由 這個(gè)資源就直接使用,否則返回為空
        if (resource.exists()) {
          return new ModelAndView(new DefaultErrorViewResolver.HtmlResourceView(resource), model);
        }
      } catch (Exception var8) {
      }
    }
     
    return null;
  }

步驟:

一旦系統(tǒng)出現(xiàn) 4xx 或者 5xx 之類的錯(cuò)誤,ErrorPageCustomizer 就會生效(定制錯(cuò)誤的響應(yīng)規(guī)則),就會來到 /error 請求,會被BasicErrorController

處理。

①響應(yīng)頁面 去哪個(gè)頁面由 DefaultErrorViewResolver 決定

protected ModelAndView resolveErrorView(HttpServletRequest request, HttpServletResponse response, HttpStatus status, Map model) {
  Iterator var5 = this.errorViewResolvers.iterator();     //解析所有的 ErrorViewResolver 得到 modelAndView
  ModelAndView modelAndView;
  do {
    if (!var5.hasNext()) {
      return null;
    }
    ErrorViewResolver resolver = (ErrorViewResolver)var5.next();
    modelAndView = resolver.resolveErrorView(request, status, model);
  } while(modelAndView == null);
  return modelAndView;
}

2.錯(cuò)誤信息的定制

①如何定制錯(cuò)誤頁面

1>有模板引擎的情況下: error/狀態(tài)碼 ;【將錯(cuò)誤頁面命名為 錯(cuò)誤碼.html 放在模板引擎文件夾下的 error 文件夾下】,發(fā)生此狀態(tài)碼的錯(cuò)誤就來到

對應(yīng)的頁面;

我們可以使用 4xx 和 5xx 作為錯(cuò)誤頁面的文件名來匹配這種類型的所欲錯(cuò)誤,精確優(yōu)先(優(yōu)先尋找精確的 狀態(tài)碼.html );

頁面能夠獲取到的信息

timestamp :時(shí)間戳

status : 狀態(tài)碼

exception : 異常對象

message : 異常消息

errors : JSR303數(shù)據(jù)校驗(yàn)的錯(cuò)誤都在這兒

2>.沒有模板引擎(模板引擎找不到這個(gè)頁面),靜態(tài)資源文件夾下找

3>.以上都沒有錯(cuò)誤頁面,就默認(rèn)來到 springboot 默認(rèn)的錯(cuò)誤頁面

②、自定義異常處理&返回定制json數(shù)據(jù);

@ControllerAdvice
public class MyExceptionHandler {
 
  @ResponseBody
  @ExceptionHandler(UserNotExistException.class)
  public Map handleException(Exception e){
    Map map = new HashMap<>();
    map.put("code","user.notexist");
    map.put("message",e.getMessage());
    return map;
  }
}
//通過異常處理器,但沒有自適應(yīng)效果(瀏覽器返回頁面,客戶端訪問返回json數(shù)據(jù))

2)、轉(zhuǎn)發(fā)到/error進(jìn)行自適應(yīng)響應(yīng)效果處理

@RequestMapping(
  produces = {"text/html"}
)
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {     //獲取錯(cuò)誤的狀態(tài)碼,在分析的過程中,要注意參數(shù)從哪兒來?  =======》前領(lǐng)導(dǎo)的一句話,哈哈……
  HttpStatus status = this.getStatus(request);
  Map model = Collections.unmodifiableMap(this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.TEXT_HTML)));
  response.setStatus(status.value());    //依據(jù)錯(cuò)誤狀態(tài)碼解析錯(cuò)誤試圖,如果直接轉(zhuǎn)發(fā),不指定錯(cuò)誤狀態(tài)碼則試圖解析出錯(cuò)(直接轉(zhuǎn)發(fā)狀態(tài)碼為 200 ,到不了定制的 4xx 5xx 的頁面)
  ModelAndView modelAndView = this.resolveErrorView(request, response, status, model);
  return modelAndView != null ? modelAndView : new ModelAndView("error", model);
}
@ExceptionHandler(UserNotExistException.class)
  public String handleException(Exception e, HttpServletRequest request){
    Map map = new HashMap<>();
    //傳入我們自己的錯(cuò)誤狀態(tài)碼 4xx 5xx,否則就不會進(jìn)入定制錯(cuò)誤頁面的解析流程
    /**
     * Integer statusCode = (Integer) request
     .getAttribute("javax.servlet.error.status_code");
     */
    request.setAttribute("javax.servlet.error.status_code",500);
    map.put("code","user.notexist");
    map.put("message",e.getMessage());
    //轉(zhuǎn)發(fā)到/error
    return "forward:/error";
  }

3)、將我們的定制數(shù)據(jù)攜帶出去;======》即修改model中的值即可

出現(xiàn)錯(cuò)誤以后,會來到/error請求,會被BasicErrorController處理,響應(yīng)出去可以獲取的數(shù)據(jù)是由getErrorAttributes得到的(是AbstractErrorController(ErrorController)規(guī)定的方法);

1、完全來編寫一個(gè)ErrorController的實(shí)現(xiàn)類【或者是編寫AbstractErrorController的子類】,放在容器中;

2、頁面上能用的數(shù)據(jù),或者是json返回能用的數(shù)據(jù)都是通過errorAttributes.getErrorAttributes得到;

容器中DefaultErrorAttributes.getErrorAttributes();默認(rèn)進(jìn)行數(shù)據(jù)處理的;

自定義ErrorAttributes

//給容器中加入我們自己定義的ErrorAttributes
@Component
public class MyErrorAttributes extends DefaultErrorAttributes {
 
  @Override
  public Map getErrorAttributes(RequestAttributes requestAttributes, boolean includeStackTrace) {
    Map map = super.getErrorAttributes(requestAttributes, includeStackTrace);
    map.put("company","atguigu");
    return map;
  }
}

最終的效果:響應(yīng)是自適應(yīng)的,可以通過定制ErrorAttributes改變需要返回的內(nèi)容,

如何實(shí)現(xiàn)Springboot錯(cuò)誤處理機(jī)制

看完這篇關(guān)于如何實(shí)現(xiàn)Springboot錯(cuò)誤處理機(jī)制的文章,如果覺得文章內(nèi)容寫得不錯(cuò)的話,可以把它分享出去給更多人看到。


本文題目:如何實(shí)現(xiàn)Springboot錯(cuò)誤處理機(jī)制
文章分享:http://weahome.cn/article/ipscgi.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部