自定義 ZuulFilter拋出異常

前提:
項(xiàng)目中統(tǒng)一使用 HttpResponseCode 來(lái)作為服務(wù)正常的返回, body 中放具體返回的內(nèi)容.
如果拋出異常的情況下,期望 code 是4XX,body 中存放錯(cuò)誤信息給用戶友好提示
但是,在SpringCloud 中默認(rèn)的異常拋出是一個(gè)包含五個(gè)字段的對(duì)象.如下:

{
    "timestamp": 1513303905953,
    "status": 400,
    "error": "Bad Request",
    "exception": "org.springframework.web.bind.MissingServletRequestParameterException",
    "message": "Required Integer parameter 'userId' is not present",
    "path": "/info"
}

我們需要的是這樣一種情況的:

Screen Shot 2017-12-15 at 2.23.05 PM.png

接下來(lái)我們來(lái)實(shí)現(xiàn)這種情況.

首先,第一個(gè)想到的是使用 @ControllerAdvice 來(lái)做全局的異常攔截,對(duì)異常進(jìn)行處理
Screen Shot 2017-12-15 at 2.45.26 PM.png

但是,重啟過(guò)后并沒(méi)有什么作用,忽然想到@ControllerAdvice 應(yīng)該是只處理到達(dá) Controller 中的請(qǐng)求才能被攔截到,而 filter 在 controller 之前,所以攔截不到.那么就要找其他方法來(lái)處理.

ZuulFilter 中的 FilterType 中有一個(gè) Error 的處理器.查找這方面資料StackOverflow,別人也遇到過(guò)這種情況需要同樣的處理.
解決方案如下:

  1. error 類型的 zuulFilter
  2. 執(zhí)行順序在默認(rèn)的 SendErrorFilter (index=0)之前,因此,我們?cè)O(shè)置為-1
  3. should 方法中檢查有沒(méi)有拋出異常
  4. run 方法中對(duì)異常進(jìn)行處理

代碼如下:

@Component
public class ErrorFilter extends ZuulFilter {
    private final Logger log = LoggerFactory.getLogger(Http401UnauthorizedEntryPoint.class);

    @Override
    public String filterType() {
        return "error";
    }

    @Override
    public int filterOrder() {
        //需要在默認(rèn)的 SendErrorFilter 之前
        return -1; // Needs to run before SendErrorFilter which has filterOrder == 0
    }

    @Override
    public boolean shouldFilter() {
        // only forward to errorPath if it hasn't been forwarded to already
        return RequestContext.getCurrentContext().containsKey("throwable");
    }

    @Override
    public Object run() {
        try {
            RequestContext ctx = RequestContext.getCurrentContext();
            Object e = ctx.get("throwable");

            if (e != null && e instanceof ZuulException) {
                ZuulException zuulException = (ZuulException) e;

                // Remove error code to prevent further error handling in follow up filters
                // 刪除該異常信息,不然在下一個(gè)過(guò)濾器中還會(huì)被執(zhí)行處理
                ctx.remove("throwable");
                // 根據(jù)具體的業(yè)務(wù)邏輯來(lái)處理
                ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
                 
            }
        } catch (Exception ex) {
            log.error("Exception filtering in custom error filter", ex);
            ReflectionUtils.rethrowRuntimeException(ex);
        }
        return null;
    }
}

注意:可能是因?yàn)榘姹静煌? 上文鏈接解決方案中shoutFilter 中異常信息不一致,導(dǎo)致不能進(jìn)入處理

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,699評(píng)論 19 139
  • iOS網(wǎng)絡(luò)架構(gòu)討論梳理整理中。。。 其實(shí)如果沒(méi)有APIManager這一層是沒(méi)法使用delegate的,畢竟多個(gè)單...
    yhtang閱讀 5,494評(píng)論 1 23
  • JAVA異常與異常處理詳解 一、異常簡(jiǎn)介 什么是異常? 異常就是有異于常態(tài),和正常情況不一樣,有錯(cuò)誤出錯(cuò)。在jav...
    java大濕兄閱讀 1,045評(píng)論 0 11
  • 原文鏈接:http://m.itdecent.cn/p/6b816c609669 前傳 出于興趣最近開(kāi)始研究k...
    懸筆e絕閱讀 7,362評(píng)論 1 11
  • 01 “我再也不相信愛(ài)情了,我再也不會(huì)幸福了……”如果這是一個(gè)剛剛失戀或者失婚的人跟你傾訴,你大概會(huì)打起十二分的精...
    學(xué)徒賢芳閱讀 639評(píng)論 0 8

友情鏈接更多精彩內(nèi)容