Toggle navigation
Java课程
个人开源
技术文章
我的博客
Spring Cloud
Spring Boot
关于
赞助
登录
|
注册
支付宝扫一扫帮助发展吧~
微信扫一扫帮助发展吧~
更多技术分享尽在公众号 ~ 关注下吧!
Spring Cloud Zuul记录接口响应数据
尹吉欢
2018-08-06 09:23:43.0
0条评论
726人阅读
版权声明:转载请先联系作者并标记出处。
springcloud
去注册
去登录
登录后发表
去注册
去登录
登录后发表
系统在生产环境出现问题时,排查问题最好的方式就是查看日志了,日志的记录尽量详细,这样你才能快速定位问题。 如果需要在Zuul中进行详细的日志记录,这两种日志必不可少。 - API请求信息 - API响应信息 前面有介绍过如何获取请求信息,文章请查看[《Spring Cloud Zuul过滤器获取请求参数问题》](http://cxytiandi.com/blog/detail/20343)。 今天正好又有一位朋友问我如何获取响应的数据,抽时间给大家写篇文章简单分享下。 熟悉Zuul的朋友都知道,Zuul中有4种类型过滤器,每种都有特定的使用场景,要想记录响应数据,那么必须是在请求路由到了具体的服务之后,返回了才有数据,这种需求就适合用post过滤器来实现了。 这边给大家介绍两种方式获取响应数据: **第一种** ``` 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中可以看到下面一段代码: ``` 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
headers) throws IOException { RequestContext context = RequestContext.getCurrentContext(); context.setResponseStatusCode(status); if (entity != null) { context.setResponseDataStream(entity); } // ..... } ``` 第二天又问了另外一个问题,怎么获取response的contentType? 需求是可以区分是正常的数据响应还是文件下载: 这位朋友获取的代码是: ``` HttpServletResponse response = ctx.getResponse(); response.getContentType() ``` 他说上面的方式获取不到? 我给大家介绍两种获取方式,如下: **第一种** ``` List
> headerList = RequestContext.getCurrentContext().getOriginResponseHeaders(); for (Pair
pair : headerList) { if (pair.first().equals("Content-Type")) { System.err.println(pair.second()); } } ``` **第二种** ``` Object zuulResponse = RequestContext.getCurrentContext().get("zuulResponse"); if (zuulResponse != null) { RibbonHttpResponse resp = (RibbonHttpResponse) zuulResponse; System.err.println(resp.getHeaders().getContentType().toString()); } ``` ## 推荐下我的新书《Spring Cloud微服务-全栈技术与案例解析》 新书购买:单本75折包邮  