阅读 117

WebFlux(reactor)中获取完整response body数据

场景
使用Spring Cloud Gateway(SCG)时,想在网关日志中输出返回日志,但由于数据流只能被读取一次,必须使用特定方式进行重写才能正常返回到前端。

处理过程
起初使用fluxBody.map读取数据流,会出现多次输出的情况,由于使用的时reactor框架处理数据,导致会出现将一个结果集分为多次处理,会执行多次map,效果不理想。
Flux fluxBody = (Flux) body;
Mono newMono = super.writeWith(
fluxBody.map(dataBuffer -> {
String respBody = dataBuffer.toString(StandardCharsets.UTF_8);
if (respBody.length() > maxLogLength) {
respBody = respBody.substring(0, maxLogLength);
}
if (PathUtil.checkPath(request.getPath().value(), contentLengthUrls)) {
httpHeaders.setContentLength(respBody.length());
}
//匹配是否需要生成slat
if (PathUtil.checkPath(request.getPath().value(), loginUrls)) {
String salt = createSlat(JSON.parseObject(respBody).getString("token"));
if (StringUtils.isEmpty(salt)) {
logger.warn("CreateSalt error:id={}", request.getHeaders().getFirst(HEADER_REQUEST_ID));
} else {
httpHeaders.add("s", salt);
}
}
logger.info("fgwResponse : id={},body = {}", request.getHeaders().getFirst(HEADER_REQUEST_ID), respBody);
return bufferFactory.wrap(content);
})
);
//request中有salt则返回到response中
logger.info("fgwResponse : id={},resp = {}", request.getHeaders().getFirst(HEADER_REQUEST_ID), JSON.toJSONString(exchange.getResponse()));
return newMono;
最后查看github上的讨论,开发者给出DataBufferUtils.join(body) .doOnNext的方式。
@Component
public class LogRespFilter implements GlobalFilter, Ordered {

@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpResponse originalResponse = exchange.getResponse();
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono writeWith(Publisher body) {
//修改header
HttpHeaders httpHeaders = originalResponse.getHeaders();
httpHeaders.add("xxxxxx","aaaaaa");
//输出返回结果
if (body instanceof Flux) {
Mono newMono = super.writeWith(
DataBufferUtils.join(body)
.doOnNext(dataBuffer -> {
String respBody = dataBuffer.toString(StandardCharsets.UTF_8);
//输出body
logger.info("fgwResponse : body = {}", respBody);
})
);
//输出response,不包含body
logger.info("fgwResponse : resp = {}", JSON.toJSONString(exchange.getResponse()));
return newMono;

}
return super.writeWith(body);
}
};
return chain.filter(exchange.mutate().response(decoratedResponse).build());
}
}

————————————————
版权声明:本文为CSDN博主「lizz666」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lizz861109/article/details/106303929

原文:https://www.cnblogs.com/duanxz/p/14829965.html

文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐