如何在Spring的ExceptionHandler中獲取Body

目前是用SpringMVC時(shí)马僻,往往使用ExceptionHandler去做Controller層的統(tǒng)一異常處理。
使用ExceptionHandler注解的異常處理方法可以使用很靈活的方法簽名扰藕。


可使用的參數(shù)類型

  • 一個(gè)異常參數(shù)。聲明一個(gè)一般性的異常或者更加具體的異常
  • Request 和/或 response 對(duì)象(Servlet API 或 Portlet API)逝钥⌒合桑可以選擇一個(gè)特定 - request/response的類型糕再,比如ServletRequest / HttpServletRequest
  • Session 對(duì)象
  • WebRequest 或 NativeWebRequest
  • Locale
  • InputStream / Reader 訪問請(qǐng)求內(nèi)容
  • OutputStream / Writer 生成響應(yīng)內(nèi)容
  • Model

異常處理方法支持的返回值類型

  • ModelAndView 對(duì)象 (Servlet MVC or Portlet MVC)
  • Model 對(duì)象
  • Map 對(duì)象,
  • View 對(duì)象
  • 被解析成一個(gè)視圖名稱的String 值
  • @ResponseBody 注解的方法 (僅限Servlet) 設(shè)置響應(yīng)內(nèi)容
  • HttpEntity<?> 或 ResponseEntity<?> (僅限Servlet) 設(shè)置響應(yīng)頭和響應(yīng)內(nèi)容
  • void。方法自己處理了響應(yīng)玉转。

如何在異常發(fā)生時(shí)輸出請(qǐng)求

發(fā)生異常時(shí)突想,不僅僅需要輸出異常本身,經(jīng)常還需要根據(jù)Request的具體內(nèi)容來分析究抓、排查問題猾担。
比如HttpRequestMethodNotSupportedException、HttpMessageConversionException等等刺下,這些異常發(fā)生在業(yè)務(wù)代碼處理之前绑嘹,業(yè)務(wù)代碼是無法獲取到request的數(shù)據(jù)的,發(fā)生異常時(shí)如果能夠看到請(qǐng)求body的具體內(nèi)容橘茉,那么處理起來就可以對(duì)癥下藥工腋,事半功倍。
說起來簡單畅卓,做起來卻不是很順當(dāng)擅腰,雖然ExcelptionHandler中可以傳入ServerletRequest作為入?yún)ⅲ荢erverletRequest的inputStream只能被讀取一次髓介,發(fā)生異常的時(shí)候再想去讀取body只能悲催的得到一個(gè)已經(jīng)Closed的Stream惕鼓。
找了一大圈,發(fā)現(xiàn)了一個(gè)有效的方法唐础,感謝StackOverflow -_-~

使用ContentCachingRequestWrapper

  1. 通過過濾器將ServerletRequest封裝成ContentCachingRequestWrapper箱歧,body被讀取后,會(huì)被它緩存一膨。
@Component
   public class RequestWrapperFilter extends OncePerRequestFilter {

       @Override
       protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
           filterChain.doFilter(new ContentCachingRequestWrapper(httpServletRequest), httpServletResponse);
       }
   }
  1. ExceptionHandler傳入ServletRequest呀邢,此時(shí)的ServletRequest就是ContentCachingRequestWrapper,輸出即可

    @ExceptionHandler({HttpRequestMethodNotSupportedException.class,
            HttpMessageConversionException.class,
            TypeMismatchException.class})
    public ResponseEntity<Response> returnMediaTypeNotSupportError(Exception ex, ServletRequest request) {
        if (request != null && request instanceof ContentCachingRequestWrapper) {
            ContentCachingRequestWrapper wrapper = (ContentCachingRequestWrapper) request;
            logger.warn("BAD_REQUEST_BODY:{}", StringUtils.toEncodedString(wrapper.getContentAsByteArray(), Charset.forName(wrapper.getCharacterEncoding())));
        }
           .....
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末豹绪,一起剝皮案震驚了整個(gè)濱河市价淌,隨后出現(xiàn)的幾起案子申眼,更是在濱河造成了極大的恐慌,老刑警劉巖蝉衣,帶你破解...
    沈念sama閱讀 212,542評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件括尸,死亡現(xiàn)場離奇詭異,居然都是意外死亡病毡,警方通過查閱死者的電腦和手機(jī)濒翻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來啦膜,“玉大人有送,你說我怎么就攤上這事∩遥” “怎么了雀摘?”我有些...
    開封第一講書人閱讀 158,021評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長八拱。 經(jīng)常有香客問我阵赠,道長,這世上最難降的妖魔是什么乘粒? 我笑而不...
    開封第一講書人閱讀 56,682評(píng)論 1 284
  • 正文 為了忘掉前任豌注,我火速辦了婚禮,結(jié)果婚禮上灯萍,老公的妹妹穿的比我還像新娘轧铁。我一直安慰自己,他們只是感情好旦棉,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評(píng)論 6 386
  • 文/花漫 我一把揭開白布齿风。 她就那樣靜靜地躺著,像睡著了一般绑洛。 火紅的嫁衣襯著肌膚如雪救斑。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,985評(píng)論 1 291
  • 那天真屯,我揣著相機(jī)與錄音脸候,去河邊找鬼。 笑死绑蔫,一個(gè)胖子當(dāng)著我的面吹牛运沦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播配深,決...
    沈念sama閱讀 39,107評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼携添,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了篓叶?” 一聲冷哼從身側(cè)響起烈掠,我...
    開封第一講書人閱讀 37,845評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤羞秤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后左敌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瘾蛋,經(jīng)...
    沈念sama閱讀 44,299評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評(píng)論 2 327
  • 正文 我和宋清朗相戀三年矫限,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了瘦黑。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,747評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡奇唤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出匹摇,到底是詐尸還是另有隱情咬扇,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評(píng)論 4 333
  • 正文 年R本政府宣布廊勃,位于F島的核電站懈贺,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏坡垫。R本人自食惡果不足惜梭灿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望冰悠。 院中可真熱鬧堡妒,春花似錦、人聲如沸溉卓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽桑寨。三九已至伏尼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間尉尾,已是汗流浹背爆阶。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評(píng)論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留沙咏,地道東北人辨图。 一個(gè)月前我還...
    沈念sama閱讀 46,545評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像芭碍,于是被迫代替她去往敵國和親徒役。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評(píng)論 2 350

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理窖壕,服務(wù)發(fā)現(xiàn)忧勿,斷路器杉女,智...
    卡卡羅2017閱讀 134,637評(píng)論 18 139
  • 這部分主要是與Java Web和Web Service相關(guān)的面試題。 96鸳吸、闡述Servlet和CGI的區(qū)別? 答...
    雜貨鋪老板閱讀 1,400評(píng)論 0 10
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法熏挎,類相關(guān)的語法,內(nèi)部類的語法晌砾,繼承相關(guān)的語法坎拐,異常的語法,線程的語...
    子非魚_t_閱讀 31,602評(píng)論 18 399
  • 從三月份找實(shí)習(xí)到現(xiàn)在养匈,面了一些公司哼勇,掛了不少,但最終還是拿到小米呕乎、百度积担、阿里、京東猬仁、新浪帝璧、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,218評(píng)論 11 349
  • 不知不覺間…我好像喜歡上了他 開始對(duì)他的一舉一動(dòng)都十分關(guān)注 就連他每次走過我的窗前 我都會(huì)抬起頭 癡癡的望著他 看...
    舊顏難忘閱讀 124評(píng)論 0 0