如何在Spring Webflux Java中记录请求正文 [英] How to log request body in spring Webflux Java
问题描述
我在 POST 请求中接收到一些 XML 负载,并希望看到接收到的负载以进行调试.
I am receiving some XML payload in a POST request and want to see the payload as received for debugging purposes.
下面(我的自定义 WebFilter)代码按预期记录了 URI 和请求标头,但没有记录请求正文/有效负载,我的反应式代码一定有问题 -
Below (my custom WebFilter) code logs the URI and request headers as expected but not the request body/payload, must be something wrong with my reactive code -
final ServerHttpRequest request = exchange.getRequest();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
LOGGER.info("Request: uri={}", request.getURI());
LOGGER.info("Request: headers={}", request.getHeaders().entrySet());
request.getBody().doOnNext(dataBuffer -> {
try {
Channels.newChannel(baos).write(dataBuffer.asByteBuffer().asReadOnlyBuffer());
String body = new String(baos.toByteArray());
LOGGER.info("Request: payload={}", body);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
我查看了布赖恩对下面帖子的回复并遵循了它,但由于没有代码,我可能犯了一些愚蠢的错误
I have looked at Brian's response for post below and followed it but since there is no code, I am probably making some silly mistake
更新代码
@Configuration
public class RequestFilter implements WebFilter {
private static final Logger LOGGER = LoggerFactory.getLogger(RequestFilter.class);
@Override
@Order(Ordered.HIGHEST_PRECEDENCE)
public Mono<Void> filter(ServerWebExchange serverWebExchange,
WebFilterChain webFilterChain) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
serverWebExchange.getRequest().getBody().doOnNext(dataBuffer -> {
try {
Channels.newChannel(baos).write(dataBuffer.asByteBuffer().asReadOnlyBuffer());
String body = new String(baos.toByteArray());
LOGGER.info("Request: payload={}", body);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
return webFilterChain.filter(serverWebExchange);
}
}
推荐答案
除了在错误的位置提取主体之外,您的做法部分正确.您必须在 ServerHttpRequestDecorator
实现中执行此操作并将其插入 WebFilter
实现中.
You are doing it partially right except that you are extracting the body at the wrong place. You will have to do it in a ServerHttpRequestDecorator
implementation and plug it in the WebFilter
implementation.
public class RequestLoggingDecorator extends ServerHttpRequestDecorator {
private static final Logger LOGGER = LoggerFactory.getLogger(RequestLoggingDecorator.class);
public RequestLoggingDecorator(ServerHttpRequest delegate) {
super(delegate);
}
@Override
public Flux<DataBuffer> getBody() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
return super.getBody().doOnNext(dataBuffer -> {
try {
Channels.newChannel(baos).write(dataBuffer.asByteBuffer().asReadOnlyBuffer());
String body = new String(baos.toByteArray(), StandardCharsets.UTF_8);
LOGGER.info("Request: payload={}", body);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
然后您可以在 WebFilter
实现中进行如下配置:
Then you can configure this in a WebFilter
implementation as follows:
@Configuration
public class RequestLoggingFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
ServerWebExchangeDecorator decorator =
new ServerWebExchangeDecorator(serverWebExchange) {
@Override
public ServerHttpRequest getRequest() {
return new RequestLoggingDecorator(serverWebExchange.getRequest());
}
};
return webFilterChain.filter(decorator);
}
}
这应该在每个传入的 Http 请求上记录您的请求正文.
This should log your request body on every incoming Http request.
这篇关于如何在Spring Webflux Java中记录请求正文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!