RestTemplate 日志打印

思路

为 RestTemplate 添加一个拦截器,发送请求前打印请求相关日志,发送请求后打印响应结果. 由于 InputStream 按照规范只能读取一次,初始想法是打印结果后重新构建一个 ClientHttpResponse 对象返回. 无意发现 BufferingClientHttpResponseWrapper 读取 response 的时候,他会将其缓存在自己对象,达到支持重复读的效果,使用方式只需以 BufferingClientHttpRequestFactory 将自己原来的 http客户端工厂包装一层即可.

okhttp 依赖引入

<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.13.0</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.11.0</version>
</dependency>

RestTemplate 配置类

import lombok.extern.slf4j.Slf4j;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.apache.commons.io.IOUtils;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.client.*;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;
@Slf4j
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder
.requestFactory(this::httpRequestFactory)
.additionalInterceptors(loggingRequestInterceptor())
.build();
}
/**
* 日志打印
*
* @return 自定义 http 请求拦截器
*/
public ClientHttpRequestInterceptor loggingRequestInterceptor() {
return (request, body, execution) -> {
log.debug("request_uri : \t{}", request.getURI());
log.debug("request_method : \t{}", request.getMethod());
log.debug("request_headers : \t{}", request.getHeaders());
log.debug("request_body : \t{}", new String(body, StandardCharsets.UTF_8));
ClientHttpResponse response = execution.execute(request, body);
log.debug("response_status : \t{}", response.getStatusText());
log.debug("response_headers : \t{}", response.getHeaders());
MediaType contentType = response.getHeaders().getContentType();
if (MediaType.APPLICATION_JSON.isCompatibleWith(contentType)) {
log.debug("response_body : \t{}", IOUtils.toString(response.getBody(), StandardCharsets.UTF_8));
} else {
log.debug("response_content_type is not application/json");
}
return response;
};
}
public ClientHttpRequestFactory httpRequestFactory() {
OkHttpClient.Builder builder = new OkHttpClient()
.newBuilder()
.readTimeout(600, TimeUnit.SECONDS)
.writeTimeout(10, TimeUnit.SECONDS)
.connectTimeout(1, TimeUnit.SECONDS);
builder.setConnectionPool$okhttp(new ConnectionPool(500, 30, TimeUnit.SECONDS));
return new BufferingClientHttpRequestFactory(new OkHttp3ClientHttpRequestFactory(builder.build()));
}
}
posted @   临渊不羡渔  阅读(776)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
点击右上角即可分享
微信分享提示