配置环境所使用的相关依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.13</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.gmm</groupId> <artifactId>rest-template-okhttp3</artifactId> <version>0.0.1-SNAPSHOT</version> <name>rest-template-okhttp3</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency> <!-- okhttp --> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> </dependency> <dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> <version>2.0.27</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <!-- <version>6.0.10</version>--> <version>5.3.28</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
接下来配置RestTemplate,我们使用okhttp作为http请求连接工厂
private static SSLContext getSslContext(TrustManager[] trustAllCerts) throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
return sc;
}
private static X509TrustManager getTrustManager() {
X509TrustManager x509TrustManager = new X509TrustManager() {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
};
return x509TrustManager;
}
@Bean
public RestTemplate restTemplate() throws NoSuchAlgorithmException, KeyManagementException {
X509TrustManager x509TrustManager = getTrustManager();
TrustManager[] trustAllCerts = new TrustManager[] { x509TrustManager };
SSLContext sc = getSslContext(trustAllCerts);
// SSL证书设置
SSLSocketFactory socketFactory = sc.getSocketFactory();
OkHttpClient.Builder bd = new okhttp3.OkHttpClient.Builder();
bd.sslSocketFactory(socketFactory, x509TrustManager);
// http连接工厂设置
OkHttp3ClientHttpRequestFactory okHttp3ClientHttpRequestFactory = new OkHttp3ClientHttpRequestFactory(bd.build());
okHttp3ClientHttpRequestFactory.setConnectTimeout(5000);
okHttp3ClientHttpRequestFactory.setReadTimeout(8000);
okHttp3ClientHttpRequestFactory.setWriteTimeout(8000);
RestTemplate restTemplate = new RestTemplate(okHttp3ClientHttpRequestFactory);
// 添加拦截器
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
MyRequestInterceptor myRequestInterceptor = new MyRequestInterceptor();
interceptors.add(myRequestInterceptor);
restTemplate.setInterceptors(interceptors);
// 中文乱码,主要是 StringHttpMessageConverter的默认编码为ISO导致的
List<HttpMessageConverter<?>> list = restTemplate.getMessageConverters();
for (HttpMessageConverter converter : list) {
if (converter instanceof StringHttpMessageConverter) {
((StringHttpMessageConverter) converter).setDefaultCharset(StandardCharsets.UTF_8);
break;
}
}
return restTemplate;
}
@Slf4j
public class MyRequestInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] body, ClientHttpRequestExecution clientHttpRequestExecution) throws IOException {
//记录请求开始时间
StopWatch stopWatch = new StopWatch();
stopWatch.start();
//执行请求
ClientHttpResponse response = clientHttpRequestExecution.execute(httpRequest, body);
//执行完毕后,这里要创建备份,要不然会报io提前关闭的异常错误
ClientHttpResponse responseCopy = new BufferingClientHttpResponseWrapper(response);
//记录请求结束时间
stopWatch.stop();
//获取响应内容
StringBuilder resBody = new StringBuilder();
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(responseCopy.getBody(), Charset.forName("UTF-8")))) {
String line = bufferedReader.readLine();
while (line != null) {
resBody.append(line);
line = bufferedReader.readLine();
}
}
//获取请求内容
String reqBody = "";
//这里可以自定义想打印什么方法或者请求的内容,如下只打印post请求的日志,因为这时候才会带上body
if (httpRequest.getHeaders().getContentType() != null && "POST".equals(httpRequest.getMethod().name())) {
String requestBody = new String(body, Charset.forName("UTF-8"));
// String contentType = httpRequest.getHeaders().getContentType().toString();
//这里可以对contentType做一些判断,针对其格式化请求体的内容,如"application/x-www-form-urlencoded"格式会附带一些boundary(分割线)的内容
reqBody = requestBody;
}
//打印日志的格式可以自定义
log.info(JSON.toJSONString(RestLog.builder().costTime(stopWatch.getLastTaskTimeMillis()).headers(httpRequest.getHeaders()).method(httpRequest.getMethodValue())
.reqUrl(httpRequest.getURI().toString()).reqBody(reqBody).resBody(resBody.toString()).resStatus(responseCopy.getRawStatusCode()).build()));
return responseCopy;
}
/**
* 响应内容备份
*/
final class BufferingClientHttpResponseWrapper implements ClientHttpResponse {
private final ClientHttpResponse response;
private byte[] body;
BufferingClientHttpResponseWrapper(ClientHttpResponse response) {
this.response = response;
}
@Override
public HttpStatus getStatusCode() throws IOException {
return this.response.getStatusCode();
}
@Override
public int getRawStatusCode() throws IOException {
return this.response.getRawStatusCode();
}
@Override
public String getStatusText() throws IOException {
return this.response.getStatusText();
}
@Override
public HttpHeaders getHeaders() {
return this.response.getHeaders();
}
@Override
public InputStream getBody() throws IOException {
if (this.body == null) {
this.body = StreamUtils.copyToByteArray(this.response.getBody());
}
return new ByteArrayInputStream(this.body);
}
@Override
public void close() {
this.response.close();
}
}
/**
* 定义日志的字段
*/
@Data
@Builder
private static class RestLog {
private String reqUrl;
private String method;
private HttpHeaders headers;
private String reqBody;
private String resBody;
private long costTime;
private int resStatus;
}
}
相关测试
@Resource
private RestTemplate restTemplate;
@Test
public void httpGetTest2() {
String url = "https://www.baidu.com";
ResponseEntity<String> htmlEntity = restTemplate.getForEntity(url, String.class);
HttpStatus status = htmlEntity.getStatusCode();
System.out.println("返回http状态码 ==>> " + status.value());
System.out.println("返回http状态码 ==>> " + htmlEntity.getStatusCode());
System.out.println("返回http状态码 ==>> " + htmlEntity.getStatusCodeValue());
HttpHeaders headers = htmlEntity.getHeaders();
System.out.println(headers.toString());
String htmlBody = htmlEntity.getBody();
System.out.println("htmlBody === >> \n" + htmlBody);
String htmlString = restTemplate.getForObject(url, String.class);
System.out.println("htmlString === >>> \n" + htmlString);
}