spring boot 捕獲404錯(cuò)誤 ErrorController

之前在使用springmvc的時(shí)候可以通過(guò)在web.xml中配置404指向?qū)?yīng)的頁(yè)面狸棍,但是在spring boot是沒(méi)有web.xml的,如果沒(méi)有任何配置的話我們會(huì)得到下面的返回

瀏覽器訪問(wèn)

使用工具post

那么我想spring boot肯定為我們準(zhǔn)備好了對(duì)應(yīng)的解決方案狞贱,那就是BasicErrorController,這個(gè)繼承自AbstractErrorController蜀涨,而且是在沒(méi)有其他實(shí)現(xiàn)的時(shí)候瞎嬉,這個(gè)默認(rèn)的ErrorController才會(huì)生效,我們可以看到ErrorMvcAutoConfiguration里面的聲明厚柳,里面的ConditionalOnMissingBean就是這個(gè)意思

    @Bean
    @ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)
    public BasicErrorController basicErrorController(ErrorAttributes errorAttributes) {
        return new BasicErrorController(errorAttributes, this.serverProperties.getError(),
                this.errorViewResolvers);
    }

下面我們關(guān)注一下BasicErrorController里面的兩個(gè)方法氧枣,一個(gè)方法對(duì)面的是我們上面瀏覽器訪問(wèn)的的那個(gè)返回,一個(gè)application/json的post請(qǐng)求返回别垮,他們返回了自己預(yù)先定義的數(shù)據(jù)便监,這里我們注意下一個(gè)細(xì)節(jié),就是ModelAndView modelAndView = resolveErrorView(request, response, status, model)這一行碳想,我們進(jìn)去看下他的源碼烧董,就會(huì)知道,這里去拿返回的時(shí)候胧奔,它會(huì)默認(rèn)去項(xiàng)目的資源目錄根據(jù)請(qǐng)求的狀態(tài)碼獲取html文件返回逊移,所以如果只支持瀏覽器訪問(wèn)的get方式的話,我們直接定義好對(duì)應(yīng)的html文件就可以了
源碼

龙填,spring boot靜態(tài)默認(rèn)的默認(rèn)目錄是static胳泉,這里去error下去找view,那么只要在/resources/static/error/目錄下定義文件就行
image.png
    @RequestMapping(produces = "text/html")
    public ModelAndView errorHtml(HttpServletRequest request,
            HttpServletResponse response) {
        HttpStatus status = getStatus(request);
        Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(
                request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));
        response.setStatus(status.value());
        ModelAndView modelAndView = resolveErrorView(request, response, status, model);
        return (modelAndView == null ? new ModelAndView("error", model) : modelAndView);
    }

    @RequestMapping
    @ResponseBody
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
        Map<String, Object> body = getErrorAttributes(request,
                isIncludeStackTrace(request, MediaType.ALL));
        HttpStatus status = getStatus(request);
        return new ResponseEntity<Map<String, Object>>(body, status);
    }

但是我們更多的是接口請(qǐng)求岩遗,而且這樣靈活性太差胶背,所以我們還是自己定義一個(gè)ErrorController比較合適,然后重寫(xiě)這兩個(gè)方法喘先,errorHtml這個(gè)基本和BasicErrorController一樣,只要定義好靜態(tài)文件就行廷粒,對(duì)于error方法窘拯,我們返回自己系統(tǒng)定義的json格式數(shù)據(jù)红且,下面是具體實(shí)現(xiàn),類的其他代碼直接參考BasicErrorController的就行涤姊,定義完自己的ExceptionController之后暇番,還需要一個(gè)配置類的

 @RequestMapping(produces = "text/html")
 public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
  HttpStatus status = getStatus(request);
  log.error("接口請(qǐng)求錯(cuò)誤,http status:{}", status);
  Map<String, Object> model = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML));
  JsonResult<Object> result = new JsonResult<>(ResultCode.NOT_FOUND);
  model.put("restResponse", result);
  response.setStatus(status.value());
  ModelAndView modelAndView = resolveErrorView(request, response, status, model);
  return (modelAndView == null ? new ModelAndView("error", model) : modelAndView);
 }
 @RequestMapping
 @ResponseBody
 public ResponseEntity<JsonResult<String>> error(HttpServletRequest request) {
  HttpStatus status = getStatus(request);
  log.error("接口請(qǐng)求錯(cuò)誤思喊,http status:{}", status);
  //這里構(gòu)建自己的輸出格式,詳細(xì)代碼就不貼出,如有需要可以到代碼倉(cāng)庫(kù)查看
  if (Objects.equals(status.value(), 404)) {
   return new ResponseEntity<>(new JsonResult<>(ResultCode.NOT_FOUND), status);
  } else {
   return new ResponseEntity<>(new JsonResult<>(ResultCode.ERROR_SYSTEM), status);
  }
 }
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({Servlet.class, DispatcherServlet.class})
@AutoConfigureBefore(WebMvcAutoConfiguration.class)
@EnableConfigurationProperties(ResourceProperties.class)
public class ExceptionControllerConfig {

  private final ServerProperties serverProperties;

  private final List<ErrorViewResolver> errorViewResolvers;

  public ExceptionControllerConfig(ServerProperties serverProperties,
      ObjectProvider<List<ErrorViewResolver>> errorViewResolversProvider) {
    this.serverProperties = serverProperties;
    this.errorViewResolvers = errorViewResolversProvider.getIfAvailable();
  }

  @Bean
  public ExceptionController exceptionController(ErrorAttributes errorAttributes) {
    return new ExceptionController(errorAttributes, this.serverProperties.getError(), this.errorViewResolvers);
  }
}

這樣我們就定義好了自己的錯(cuò)誤控制器壁酬,可以根據(jù)不同的請(qǐng)求狀態(tài)碼返回自己的數(shù)據(jù);

還有一種做法

還有一種做法就是通過(guò)spring boot的配置直接完成恨课,這樣配置的顧名思義舆乔,就是在沒(méi)有handler的時(shí)候直接作為異常拋出,這樣我們的全局異常捕獲器就能夠捕獲到了剂公,然后根據(jù)不同的狀態(tài)碼返回就行希俩,但是這里需要看到的是有個(gè)add-mappings:false,就是這種情況下靜態(tài)資源是要不能訪問(wèn)的纲辽,其實(shí)是因?yàn)殪o態(tài)資源是直接訪問(wèn)颜武,不需要控制器,所以要配置成false拖吼;如果你的項(xiàng)目?jī)H僅是作為接口服務(wù)的話鳞上,那么這種方式來(lái)的更加的簡(jiǎn)單,我本來(lái)也是這么做的吊档,但是我的項(xiàng)目里面使用了swagger篙议,這個(gè)東西暴露出去的api是動(dòng)態(tài)生成的靜態(tài)文件,如果這樣配置之后籍铁,swagger也不能用了涡上,所以我還是使用了第一種方式進(jìn)行捕獲error

  spring:
    mvc:
      throw-exception-if-no-handler-found: true
    resources:
      add-mappings: false
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市拒名,隨后出現(xiàn)的幾起案子吩愧,更是在濱河造成了極大的恐慌,老刑警劉巖增显,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雁佳,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡同云,警方通過(guò)查閱死者的電腦和手機(jī)糖权,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)炸站,“玉大人星澳,你說(shuō)我怎么就攤上這事『狄祝” “怎么了禁偎?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵腿堤,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我如暖,道長(zhǎng)揪利,這世上最難降的妖魔是什么饰恕? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上傻铣,老公的妹妹穿的比我還像新娘智什。我一直安慰自己漆枚,他們只是感情好竞川,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著登淘,像睡著了一般箫老。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上黔州,一...
    開(kāi)封第一講書(shū)人閱讀 51,718評(píng)論 1 305
  • 那天耍鬓,我揣著相機(jī)與錄音,去河邊找鬼流妻。 笑死牲蜀,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的绅这。 我是一名探鬼主播涣达,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼证薇!你這毒婦竟也來(lái)了度苔?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤浑度,失蹤者是張志新(化名)和其女友劉穎寇窑,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體箩张,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡甩骏,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了先慷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饮笛。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖论熙,靈堂內(nèi)的尸體忽然破棺而出福青,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布无午,位于F島的核電站二蓝,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏指厌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一踊跟、第九天 我趴在偏房一處隱蔽的房頂上張望踩验。 院中可真熱鬧,春花似錦商玫、人聲如沸箕憾。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)袭异。三九已至,卻和暖如春炬藤,著一層夾襖步出監(jiān)牢的瞬間御铃,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工沈矿, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留上真,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓羹膳,卻偏偏與公主長(zhǎng)得像睡互,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子陵像,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容