spring cloud gateway 获得响应body记录日志问题
原创 2019-10-30 11:07 阅读(2488)次
通常在spring cloud微服务架构中,需要在网关gateway中记录日志,比如需要记录响应的body,今天我也是一直遇到响应体记录不完整的问题,body被分段,对于响应报文大一点的请求中,在响应ServerHttpResponseDecorator包装中一次取得body只能取的一段。
有问题的代码如下:
ServerHttpResponse originalResponse = exchange.getResponse();
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
Map<String, String> bodyMap = new HashMap<String, String>();
if ( body instanceof Flux) {
Flux<? extends DataBuffer> fluxBody = Flux.from(body);
Mono<Void> writeWith = super.writeWith(fluxBody.map(dataBuffer -> {
byte[] content = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(content);
// 释放掉内存
DataBufferUtils.release(dataBuffer);
// responseData就是下游系统返回的内容,可以查看修改
String responseData = new String(content, Charset.forName("UTF-8"));//只有一段
System.out.println("响应内容:{"+responseData+"}");
byte[] uppedContent = new String(content, Charset.forName("UTF-8")).getBytes();
return bufferFactory.wrap(uppedContent);
}));
}
}
};
后来查了别的大神博客找到了解决方案,把fluxBody.map变为fluxBody.buffer().map,代码如下:
// 获取response的 返回数据
ServerHttpResponse originalResponse = exchange.getResponse();
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
if ( body instanceof Flux) {
Flux<? extends DataBuffer> fluxBody = Flux.from(body);
return super.writeWith(fluxBody.buffer().map(dataBuffers -> {// 解决返回体分段传输
List<String> list = new ArrayList<String>();
dataBuffers.forEach(dataBuffer -> {
byte[] content = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(content);
DataBufferUtils.release(dataBuffer);
try {
list.add(new String(content, "utf-8"));
} catch (Exception e) {
log.error("--list.add--error", e);
}
});
String bodyString = "";
for (String string : list) {
bodyString = bodyString + string;
}
System.out.println(bodyString);
byte[] uppedContent = new String(bodyString.getBytes(), Charset.forName("UTF-8")).getBytes();
originalResponse.getHeaders().setContentLength(uppedContent.length);
return bufferFactory.wrap(uppedContent);
}));
}
};
在此记录一下代码。