Spring Cloud Zuul记录接口响应数据
系统在生产环境出现问题时,排查问题最好的方式就是查看日志了,日志的记录尽量详细,这样你才能快速定位问题。
如果需要在Zuul中进行详细的日志记录,这两种日志必不可少。
- API请求信息
- API响应信息
前面有介绍过如何获取请求信息,文章请查看《Spring Cloud Zuul过滤器获取请求参数问题》。
今天正好又有一位朋友问我如何获取响应的数据,抽时间给大家写篇文章简单分享下。
熟悉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<String, String> 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<Pair<String, String>> headerList = RequestContext.getCurrentContext().getOriginResponseHeaders();
for (Pair<String, String> 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折包邮

欢迎加入我的知识星球,一起交流技术,免费学习猿天地的课程(http://cxytiandi.com/course)


Spring Cloud Zuul记录接口响应数据的更多相关文章
- Spring Cloud Zuul网关 Filter、熔断、重试、高可用的使用方式。
时间过的很快,写springcloud(十):服务网关zuul初级篇还在半年前,现在已经是2018年了,我们继续探讨Zuul更高级的使用方式. 上篇文章主要介绍了Zuul网关使用模式,以及自动转发机制 ...
- Spring Cloud Zuul 网关使用与 OAuth2.0 认证授权服务
API 网关的出现的原因是微服务架构的出现,不同的微服务一般会有不同的服务地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题: 客户端会 ...
- Spring Cloud Zuul 概览
什么是API网关 网关这个词其实是一个硬件概念.因为按照定义,网络网关出现在网络的边缘,所以防火墙和代理服务器等相关功能 往往与之集成在一起.在家庭网络 和小型企业中,宽带路由器通常充当网络网关.它将 ...
- Spring Cloud Zuul之ZuulFilter详解
简介 Spring Cloud Zuul网关在整个微服务体系中肩负对外开放接口.请求拦截.路由转发等作用,其核心处理则是ZuulFilter ZuulFilter部分源码 Zuul Filter全部继 ...
- Spring Cloud Zuul实现IP访问控制
接着上篇文章 https://www.cnblogs.com/mxmbk/p/9569438.html IP访问限制和黑白名单如何做,需要解决以下几个问题: 1.如何识别正常访问和异常访问?(一段时间 ...
- 服务网关Spring Cloud Zuul
Spring Cloud Zuul 开发环境 idea 2019.1.2 jdk1.8.0_201 Spring Boot 2.1.9.RELEASE Spring Cloud Greenwich S ...
- 笔记:Spring Cloud Zuul 快速入门
Spring Cloud Zuul 实现了路由规则与实例的维护问题,通过 Spring Cloud Eureka 进行整合,将自身注册为 Eureka 服务治理下的应用,同时从 Eureka 中获取了 ...
- Spring Cloud Zuul 限流详解(附源码)(转)
在高并发的应用中,限流往往是一个绕不开的话题.本文详细探讨在Spring Cloud中如何实现限流. 在 Zuul 上实现限流是个不错的选择,只需要编写一个过滤器就可以了,关键在于如何实现限流的算法. ...
- Spring Cloud Zuul 中文文件上传乱码
原文地址:https://segmentfault.com/a/1190000011650034 1 描述 使用Spring Cloud Zuul进行路由转发时候吗,文件上传会造成中文乱码“?”.1. ...
随机推荐
- Docker安装使用以及mlsql的docker安装使用说明
1.检查内核版本,必须是3.10及以上 uname -r 2.安装 yum -y install docker #1.启动 docker systemctl start docker #1.1.验 ...
- 我在生产项目里是如何使用Redis发布订阅的?(一)使用场景
转载请注明出处! 导语 Redis是我们很常用的一款nosql数据库产品,我们通常会用Redis来配合关系型数据库一起使用,弥补关系型数据库的不足. 其中,Redis的发布订阅功能也是它的一大亮点.虽 ...
- 2019-7-29-win10-UWP-使用-MD5算法
原文:2019-7-29-win10-UWP-使用-MD5算法 title author date CreateTime categories win10 UWP 使用 MD5算法 lindexi 2 ...
- 通俗的讲,就是高层模块定义接口,低层模块负责实现。 Bob Martins对DIP的定义: 高层模块不应依赖于低层模块,两者应该依赖于抽象。 抽象不不应该依赖于实现,实现应该依赖于抽象。
通俗的讲,就是高层模块定义接口,低层模块负责实现. Bob Martins对DIP的定义: 高层模块不应依赖于低层模块,两者应该依赖于抽象. 抽象不不应该依赖于实现,实现应该依赖于抽象. 总结出使用D ...
- BCP 运行错误
记录下使用bcp导出csv文件时的错误: [Microsoft][ODBC SQL Server Driver][SQL Server]对象名 '***'无效问题的解决方案器 我们要对student数 ...
- 夜神模拟器怎么连接adb
夜神模拟器连接不了adb的原因主要是adb的版本与夜神模拟器adb版本不一致造成的,具体的解决办法请看下面的操作步骤. 工具/原料 电脑 安装了夜神模拟器 方法/步骤 1 使用快捷键win + ...
- 智能家居-3.基于esp8266的语音控制系统(软件篇)
智能家居-1.基于esp8266的语音控制系统(开篇) 智能家居-2.基于esp8266的语音控制系统(硬件篇) 智能家居-3.基于esp8266的语音控制系统(软件篇) 赞赏支持 QQ:505645 ...
- 将多个sass文件合并到一个文件中
将多个sass文件合并到一个文件中 应用场景:制作angular npm包的时候,定义的一些全局样式,自定义主题色这类的情况下,多个scss文件会要合并成一个文件并写到dist文件里,发布到仓库中. ...
- JAVA8新特性--集合流操作Stream
原文链接:https://blog.csdn.net/bluuusea/article/details/79967039 Stream类全路径为:java.util.stream.Stream 对St ...
- canvas的常用功能(电脑版)
前言: canvas可以单独算为前端的一大知识模块, 今天就研究一下. 先做下前文铺垫: ①创建canvas <canvas id="myCanvas" width=&quo ...