Spring Boot異常處理方案選擇

Spring Boot集成Security以及OAuth2后如何進(jìn)行異常處理

時間:2018-07-17 17:00

開發(fā)者:那年初二

全局異常處理

如果對Spring Boot比較熟悉的話逮栅,基本上都會想到使用@ControllerAdvice@RestControllerAdvice富玷、@ExceptionHandler注解來進(jìn)行全局異常處理排惨。

具體流程

  • 1八千、注解解析

    • @ControllerAdvice 捕獲 Controller 層拋出的異常,如果添加 @ResponseBody 返回信息則為JSON 格式锡宋。
    • @RestControllerAdvice 相當(dāng)于 @ControllerAdvice 與 @ResponseBody 的結(jié)合體瘫证。
    • @ExceptionHandler 統(tǒng)一處理一種類的異常,減少代碼重復(fù)率舆逃,降低復(fù)雜度蚂维。
  • 2、創(chuàng)建異常處理類

創(chuàng)建一個 GlobalExceptionHandler 類路狮,并添加上 @RestControllerAdvice 注解就可以定義出異常通知類了鸟雏,然后在定義的方法中添加上 @ExceptionHandler 即可實(shí)現(xiàn)異常的捕捉......

/**
 * 全局異常處理
 *
 * @author chentai
 * @date 2018/7/17 0001
 */
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {


    /**
     * 定義要捕獲的異常 可以多個 @ExceptionHandler({})
     *
     * @param request  request
     * @param e        exception
     * @param response response
     * @return 響應(yīng)結(jié)果
     */
    @ExceptionHandler(CustomException.class)
    public ErrorResponseEntity customExceptionHandler(HttpServletRequest request, final Exception e, HttpServletResponse response) {
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        CustomException exception = (CustomException) e;
        return new ErrorResponseEntity(exception.getCode(), exception.getMessage());
    }

    /**
     * 捕獲  RuntimeException 異常
     * TODO  如果你覺得在一個 exceptionHandler 通過  if (e instanceof xxxException) 太麻煩
     * TODO  那么你還可以自己寫多個不同的 exceptionHandler 處理不同異常
     *
     * @param request  request
     * @param e        exception
     * @param response response
     * @return 響應(yīng)結(jié)果
     */
    @ExceptionHandler(RuntimeException.class)
    public ErrorResponseEntity runtimeExceptionHandler(HttpServletRequest request, final Exception e, HttpServletResponse response) {
        response.setStatus(HttpStatus.BAD_REQUEST.value());
        RuntimeException exception = (RuntimeException) e;
        return new ErrorResponseEntity(400, exception.getMessage());
    }

    /**
     * 通用的接口映射異常處理方
     */
    @Override
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers,
                                                             HttpStatus status, WebRequest request) {
        if (ex instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException exception = (MethodArgumentNotValidException) ex;
            return new ResponseEntity<>(new ErrorResponseEntity(status.value(), exception.getBindingResult().getAllErrors().get(0).getDefaultMessage()), status);
        }
        if (ex instanceof MethodArgumentTypeMismatchException) {
            MethodArgumentTypeMismatchException exception = (MethodArgumentTypeMismatchException) ex;
            logger.error("參數(shù)轉(zhuǎn)換失敗,方法:" + exception.getParameter().getMethod().getName() + "览祖,參數(shù):" + exception.getName()
                    + ",信息:" + exception.getLocalizedMessage());
            return new ResponseEntity<>(new ErrorResponseEntity(status.value(), "參數(shù)轉(zhuǎn)換失敗"), status);
        }
        return new ResponseEntity<>(new ErrorResponseEntity(status.value(), "參數(shù)轉(zhuǎn)換失敗"), status);
    }
}
  • 3孝鹊、運(yùn)行項(xiàng)目,能夠正常進(jìn)行全局異常處理展蒂。到此為止又活,如果你的項(xiàng)目集成Security以及OAuth2只是單純使用密碼模式進(jìn)行授權(quán)認(rèn)證的話,這樣的處理方式完美符合項(xiàng)目需求锰悼。但是柳骄,如果項(xiàng)目需要使用OAuth2的授權(quán)碼模式,這樣的方式在進(jìn)行授權(quán)碼獲取的時候會拋出User must be authenticated with Spring Security before authorization can be completed異常箕般,即在完成授權(quán)之前耐薯,用戶必須通過Spring Security進(jìn)行身份驗(yàn)證。那么丝里,這時候曲初,我們應(yīng)該怎么去處理呢?其實(shí)杯聚,很簡單臼婆,既然有全局異常處理,那么就有單一異常處理幌绍。下面介紹單一異常處理颁褂。

單一異常處理

只需要在項(xiàng)目Controller類里面使用@ExceptionHandler 注解增加對應(yīng)的異常處理方法,即可捕獲該類拋出的異常并進(jìn)行處理傀广。

如颁独,項(xiàng)目中對請求參數(shù)進(jìn)行了校驗(yàn)處理,則可以在Controller類中增加如下方法:

    /**
     * @param exception
     * @return TODO: 2018/07/17 參數(shù)未通過驗(yàn)證異常
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ErrorResponse MethodArgumentNotValidHandler(MethodArgumentNotValidException exception) {
        // 解析原錯誤信息伪冰,封裝后返回誓酒,此處返回非法的字段名稱,原始值糜值,錯誤信息
        return new ErrorResponse(ResponseCode.PARAM_ERROR_CODE.getCode(),
                exception.getBindingResult().getAllErrors().get(0).getDefaultMessage());
    }

如此丰捷,當(dāng)Http請求傳入的參數(shù)出錯時坯墨,此方法會進(jìn)行相應(yīng)的處理寂汇。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末病往,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子骄瓣,更是在濱河造成了極大的恐慌停巷,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件榕栏,死亡現(xiàn)場離奇詭異畔勤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)扒磁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門庆揪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人妨托,你說我怎么就攤上這事缸榛。” “怎么了兰伤?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵内颗,是天一觀的道長。 經(jīng)常有香客問我敦腔,道長均澳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任符衔,我火速辦了婚禮找前,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘判族。我一直安慰自己纸厉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布五嫂。 她就那樣靜靜地躺著颗品,像睡著了一般。 火紅的嫁衣襯著肌膚如雪沃缘。 梳的紋絲不亂的頭發(fā)上躯枢,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機(jī)與錄音槐臀,去河邊找鬼锄蹂。 笑死,一個胖子當(dāng)著我的面吹牛水慨,可吹牛的內(nèi)容都是我干的得糜。 我是一名探鬼主播敬扛,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼朝抖!你這毒婦竟也來了啥箭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤治宣,失蹤者是張志新(化名)和其女友劉穎急侥,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體侮邀,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡坏怪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了绊茧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片铝宵。...
    茶點(diǎn)故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖华畏,靈堂內(nèi)的尸體忽然破棺而出鹏秋,到底是詐尸還是另有隱情,我是刑警寧澤唯绍,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布拼岳,位于F島的核電站,受9級特大地震影響况芒,放射性物質(zhì)發(fā)生泄漏惜纸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一绝骚、第九天 我趴在偏房一處隱蔽的房頂上張望耐版。 院中可真熱鬧,春花似錦压汪、人聲如沸粪牲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腺阳。三九已至,卻和暖如春穿香,著一層夾襖步出監(jiān)牢的瞬間亭引,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工皮获, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留焙蚓,地道東北人。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像购公,于是被迫代替她去往敵國和親萌京。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評論 2 351

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