以下是从Spring的AsyncRestTemplate
进行异步休息调用时记录请求和响应的拦截器代码。
如果我们可以在其他包中使用BufferingClientHttpResponseWrapper
,则此代码正常运行。
Here是关于BufferingClientHttpResponseWrapper
以及如何使用AsyncRestTemplate添加它的一些详细信息。
我的问题是我在AsyncRestTemplate中使用HttpComponentsAsyncClientHttpRequestFactory
时。我如何获得缓冲响应。我们不能在我的代码中使用BufferingClientHttpResponseWrapper
如下所示,因为它不是公共类。还有其他办法吗?
我知道HttpComponent AsyncHttpClient有可用的线路日志。但它将包含整个应用程序中所有AsyncResttemplates的所有日志。如果我们只想为一个模板捕获日志,那么拦截器是我认为的唯一方式。如果有其他选择,请建议。
public class AsyncRestReqResInterceptor implements AsyncClientHttpRequestInterceptor {
private static final XLogger REQ_RES_LOGGER = XLoggerFactory.getXLogger("myLogger");
@Override
public ListenableFuture<ClientHttpResponse> intercept(HttpRequest request, byte[] body, AsyncClientHttpRequestExecution execution) throws IOException {
String requestPath = request.getURI().getPath();
REQ_RES_LOGGER.debug(request.getMethod()+" "+requestPath);
String requestBody = new String(body);
REQ_RES_LOGGER.debug(requestBody);
ListenableFuture<ClientHttpResponse> listenableFuture = execution.executeAsync(request, body);
ListenableFutureAdapter<ClientHttpResponse,ClientHttpResponse> futureAdapter=
new ListenableFutureAdapter<ClientHttpResponse, ClientHttpResponse>(listenableFuture) {
@Override
protected ClientHttpResponse adapt(ClientHttpResponse adapteeResult) throws ExecutionException {
return logResponseBody(adapteeResult);
}
};
return futureAdapter;
}
private ClientHttpResponse logResponseBody(ClientHttpResponse response,boolean isImageInResponse){
try {
BufferingClientHttpResponseWrapper responseWrapper = new BufferingClientHttpResponseWrapper(response);
REQ_RES_LOGGER.debug("Response Status Code :" + responseWrapper.getStatusCode().value());
REQ_RES_LOGGER.debug("Response Status Text :" + responseWrapper.getStatusText());
if (response != null && response.getBody() != null) {
String responseXml = IOUtils.toString(responseWrapper.getBody(), Charset.defaultCharset());
REQ_RES_LOGGER.debug(responseXml);
} else {
REQ_RES_LOGGER.debug("Empty Response Body");
}
return responseWrapper;
}catch (IOException io){
REQ_RES_LOGGER.error("Unexpected Error ",io);
return response;
}
}
}
答案 0 :(得分:2)
我终于找到了使用这个类的方法。因为这是一个最终类,所以它只能在Springframework中使用。弹簧框架中有pull request用于此更改。我不确定何时将这个更改合并到框架中,但下面是将解决上述问题的类。如果我们想拦截请求和响应以进行日志记录,这些类将会很有用。
BufferingAsyncClientHttpRequestFactory
public class BufferingAsyncClientHttpRequestFactory extends
BufferingClientHttpRequestFactory
implements AsyncClientHttpRequestFactory {
private final AsyncClientHttpRequestFactory requestFactory;
/**
* Create a buffering wrapper for the given {@link ClientHttpRequestFactory}.
* @param requestFactory the target request factory to wrap
*/
public BufferingAsyncClientHttpRequestFactory(AsyncClientHttpRequestFactory requestFactory) {
super((ClientHttpRequestFactory) requestFactory);
this.requestFactory=requestFactory;
}
/**
* Indicates whether the request/response exchange for the given URI and method
* should be buffered in memory.
* <p>The default implementation returns {@code true} for all URIs and methods.
* Subclasses can override this method to change this behavior.
* @param uri the URI
* @param httpMethod the method
* @return {@code true} if the exchange should be buffered; {@code false} otherwise
*/
@Override
public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) throws IOException {
AsyncClientHttpRequest request = requestFactory.createAsyncRequest(uri, httpMethod);
if (shouldBuffer(uri, httpMethod)) {
return new BufferingAsyncClientHttpRequestWrapper(request);
}
else {
return request;
}
}
protected boolean shouldBuffer(URI uri, HttpMethod httpMethod) {
return true;
}
}
BufferingAsyncClientHttpRequestWrapper.java
public class BufferingAsyncClientHttpRequestWrapper extends AbstractBufferingAsyncClientHttpRequest {
private final AsyncClientHttpRequest request;
public BufferingAsyncClientHttpRequestWrapper(AsyncClientHttpRequest asyncClientHttpRequest){
this.request=asyncClientHttpRequest;
}
@Override
public HttpMethod getMethod() {
return this.request.getMethod();
}
@Override
public URI getURI() {
return this.request.getURI();
}
@Override
protected ListenableFuture<ClientHttpResponse> executeInternal(HttpHeaders headers, byte[] bufferedOutput) throws IOException {
this.request.getHeaders().putAll(headers);
if(bufferedOutput.length>0){
StreamUtils.copy(bufferedOutput,this.request.getBody());
}
ListenableFuture<ClientHttpResponse> futureResponse = this.request.executeAsync();
ListenableFutureAdapter<ClientHttpResponse,ClientHttpResponse> bufferedResponse =
new ListenableFutureAdapter<ClientHttpResponse, ClientHttpResponse>(futureResponse) {
@Override
protected ClientHttpResponse adapt(ClientHttpResponse adapteeResult) throws ExecutionException {
return new BufferingClientHttpResponseWrapper(adapteeResult);
}
};
return bufferedResponse;
}
}