Spring Cloud Zuul記錄接口響應數據

系統在生產環境出現問題時,排查問題最好的方式就是查看日誌了,日誌的記錄儘可能詳細,這樣你才能快速定位問題。
若是須要在Zuul中進行詳細的日誌記錄,這兩種日誌必不可少。
o API請求信息
o API響應信息
前面有介紹過如何獲取請求信息,文章請查看《Spring Cloud Zuul過濾器獲取請求參數問題》。
今天正好又有一位朋友問我如何獲取響應的數據,抽時間給你們寫篇文章簡單分享下。
熟悉Zuul的朋友都知道,Zuul中有4種類型過濾器,每種都有特定的使用場景,要想記錄響應數據,那麼必須是在請求路由到了具體的服務以後,返回了纔有數據,這種需求就適合用post過濾器來實現了。
這邊給你們介紹兩種方式獲取響應數據:
第一種ide

try {
     Object zuulResponse = RequestContext.getCurrentContext().get("zuulResponse");
     if (zuulResponse != null) {
         RibbonHttpResponse resp = (RibbonHttpResponse) zuulResponse;
         String body = IOUtils.toString(resp.getBody());
         System.err.println(body);
         resp.close();
         RequestContext.getCurrentContext().setResponseBody(body);
     }
} catch (IOException e) {
    e.printStackTrace();
}

第二種微服務

InputStream stream = RequestContext.getCurrentContext().getResponseDataStream();
try {
    String body = IOUtils.toString(stream);
    System.err.println(body);
    RequestContext.getCurrentContext().setResponseBody(body);
} catch (IOException e) {
    e.printStackTrace();
}

爲何上面兩種方式能夠取到響應內容?
在RibbonRoutingFilter或者SimpleHostRoutingFilter中能夠看到下面一段代碼:post

public Object run() {
    RequestContext context = RequestContext.getCurrentContext();
    this.helper.addIgnoredHeaders();
    try {
        RibbonCommandContext commandContext = buildCommandContext(context);
        ClientHttpResponse response = forward(commandContext);
        setResponse(response);
        return response;
    }
    catch (ZuulException ex) {
        throw new ZuulRuntimeException(ex);
    }
    catch (Exception ex) {
        throw new ZuulRuntimeException(ex);
    }
}

forward()方法對服務調用,拿到響應結果,經過setResponse()方法進行響應的設置。
protected void setResponse(ClientHttpResponse resp)
throws ClientException, IOException {
RequestContext.getCurrentContext().set("zuulResponse", resp);
this.helper.setResponse(resp.getStatusCode().value(),
resp.getBody() == null ? null : resp.getBody(), resp.getHeaders());
}
上面第一行代碼就能夠解釋咱們的第一種獲取的方法,這邊直接把響應內容加到了RequestContext中。
第二種方式的解釋就在helper.setResponse的邏輯裏面了,以下:學習

public void setResponse(int status, InputStream entity,
            MultiValueMap<String, String> headers) throws IOException {
    RequestContext context = RequestContext.getCurrentContext();
    context.setResponseStatusCode(status);
    if (entity != null) {
        context.setResponseDataStream(entity);
    }

    // .....
}

次日又問了另一個問題,怎麼獲取response的contentType?
需求是能夠區分是正常的數據響應仍是文件下載:
這位朋友獲取的代碼是:ui

HttpServletResponse response = ctx.getResponse();
response.getContentType()

他說上面的方式獲取不到?
我給你們介紹兩種獲取方式,以下:
第一種
List<Pair<String, String>> headerList = RequestContext.getCurrentContext().getOriginResponseHeaders();
for (Pair<String, String> pair : headerList) {
if (pair.first().equals("Content-Type")) {
System.err.println(pair.second());
}
}
第二種this

Object zuulResponse = RequestContext.getCurrentContext().get("zuulResponse");
if (zuulResponse != null) {
     RibbonHttpResponse resp = (RibbonHttpResponse) zuulResponse;
     System.err.println(resp.getHeaders().getContentType().toString());
}

推薦下個人新書《Spring Cloud微服務-全棧技術與案例解析》
新書購買:單本75折包郵
Spring Cloud Zuul記錄接口響應數據
猿天地
Spring Cloud Zuul記錄接口響應數據
閱讀原文,學習課程。日誌

尹吉歡
我不差錢啊
喜歡做者code

相關文章
相關標籤/搜索