spring cloud gateway 获得响应body记录日志问题

原创 2019-10-30 11:07 阅读(2454)次

通常在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);
						}));
					}
				};

在此记录一下代码。