RestTemplate+OkHttp3整合(一)

代码(HTTP、HTTPS)

一、POM

<!-okhttp->
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>3.10.0</version>
</dependency>

<!-非必要,这里解析流数据时用了一下->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>${commons-io.version}</version>
</dependency>

<!--非必要,okhttp预置日志拦截器-->
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>logging-interceptor</artifactId>
    <version>3.14.9</version>
</dependency>

二、yaml配置

# http工具配置
okhttp:
    connect-timeout: 5 #socket连接超时时间(秒)
    read-timeout: 5
    write-timeout: 5
    max-idle-connections: 10 #最大空闲连接数
    keep-alive-duration: 300 #空闲连接最多存活时间(秒)

三、RestTemplate配置

package com.test;

import lombok.extern.slf4j.Slf4j;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.*;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author shiyunlong
 * @date 2024/3/5  10:59
 */
@Configuration
public class RestTemplateConfig {
    @Value("${okhttp.connect-timeout}")
    private Integer connectTimeout;

    @Value("${okhttp.read-timeout}")
    private Integer readTimeout;

    @Value("${okhttp.write-timeout}")
    private Integer writeTimeout;

    @Value("${okhttp.max-idle-connections}")
    private Integer maxIdleConnections;

    @Value("${okhttp.keep-alive-duration}")
    private Integer keepAliveDuration;


    @Bean("httpRestTemplate")
    public RestTemplate httpRestTemplate() {
        RestTemplate restTemplate = new RestTemplate(httpRequestFactory());
        // 设置消息转换,解决中文乱码问题
        for (HttpMessageConverter<?> converter : restTemplate.getMessageConverters()) {
            // 原有的String是ISO-8859-1编码 ,设置为UTF-8
            if (converter instanceof StringHttpMessageConverter) {
                ((StringHttpMessageConverter) converter).setDefaultCharset(StandardCharsets.UTF_8);
                break;
            }
        }
        // 增加日志拦截器
        List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
        interceptors.add(new HttpRequestLogInterceptor());
        restTemplate.setInterceptors(interceptors);
        return restTemplate;
    }

    @Bean("httpsRestTemplate")
    public RestTemplate httpsRestTemplate() {
        RestTemplate restTemplate = new RestTemplate(httpsRequestFactory());
        // 设置消息转换,解决中文乱码问题
        for (HttpMessageConverter<?> converter : restTemplate.getMessageConverters()) {
            // 原有的String是ISO-8859-1编码 ,设置为UTF-8
            if (converter instanceof StringHttpMessageConverter) {
                ((StringHttpMessageConverter) converter).setDefaultCharset(StandardCharsets.UTF_8);
                break;
            }
        }
        // 增加日志拦截器
        List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
        interceptors.add(new HttpRequestLogInterceptor());
        restTemplate.setInterceptors(interceptors);
        return restTemplate;
    }

    /**
     * HTTP request factory
     */
    private ClientHttpRequestFactory httpRequestFactory() {
        // 创建连接池
        ConnectionPool connectionPool = new ConnectionPool(maxIdleConnections, keepAliveDuration, TimeUnit.SECONDS);
        // 创建okHttpClient
        OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
                .connectionPool(connectionPool)
                .connectTimeout(connectTimeout, TimeUnit.SECONDS)
                .readTimeout(readTimeout, TimeUnit.SECONDS)
                .writeTimeout(writeTimeout, TimeUnit.SECONDS)
                .hostnameVerifier((hostname, sslSession) -> true)
                .retryOnConnectionFailure(true)
                // 设置代理
//              .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8888)))
                // 拦截器
//                .addInterceptor()
                .build();
        // 返回ClientHttpRequestFactory
        return new OkHttp3ClientHttpRequestFactory(okHttpClient);
    }

    /**
     * HTTPS request factory
     */
    private ClientHttpRequestFactory httpsRequestFactory() {
        // 创建连接池
        ConnectionPool connectionPool = new ConnectionPool(maxIdleConnections, keepAliveDuration, TimeUnit.SECONDS);
        // 信任管理
        X509TrustManager trustManager = null;
        SSLContext sslContext = null;
        try {
            trustManager = new X509TrustManager() {
                @Override
                public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
                }

                @Override
                public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
                }

                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
            };
            // 信任任何链接
            sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[]{trustManager}, new SecureRandom());
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 创建okHttpClient
        OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
                .connectionPool(connectionPool)
                .connectTimeout(connectTimeout, TimeUnit.SECONDS)
                .readTimeout(readTimeout, TimeUnit.SECONDS)
                .writeTimeout(writeTimeout, TimeUnit.SECONDS)
                .hostnameVerifier((hostname, sslSession) -> true)
                .sslSocketFactory(sslContext.getSocketFactory(), trustManager)
                .retryOnConnectionFailure(true)
                // 设置代理
//              .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8888)))
                // 拦截器
//                .addInterceptor()
                .build();
        // 返回ClientHttpRequestFactory
        return new OkHttp3ClientHttpRequestFactory(okHttpClient);
    }


    @Slf4j
    static class HttpRequestLogInterceptor implements ClientHttpRequestInterceptor {
        /*
        也可以使用okhttp预置的日志拦截器,放在OkHttpClient的拦截器集合里
        <!--添加日志拦截器-->
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>logging-interceptor</artifactId>
            <version>3.14.9</version>
        </dependency>
        // 日志拦截器
        HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor();
        logInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
        */

        @Override
        public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
            requestLog(request, body);
            ClientHttpResponse response = execution.execute(request, body);
            responseLog(response);
            return response;
        }

        private void requestLog(HttpRequest request, byte[] body) {
            log.info("==================== request start ====================");
            log.info("Uri         :{}", request.getURI());
            log.info("Method      :{}", request.getMethod());
            log.info("Headers     :{}", request.getHeaders());
            log.info("Request Body:{}", new String(body, StandardCharsets.UTF_8));
            log.info("==================== request end ====================");
        }

        private void responseLog(ClientHttpResponse response) throws IOException {
            log.info("==================== response start ====================");
            log.info("Status Code  :{}", response.getStatusCode());
            log.info("Status Text  :{}", response.getStatusText());
            log.info("Headers      :{}", response.getHeaders());
            log.info("Response Body:{}", IOUtils.toString(response.getBody(), StandardCharsets.UTF_8));
            log.info("==================== response end ====================");
        }
    }
}

四、封装httpUtils

五、配置详解-更多设置项

posted @ 2024-03-05 16:25  熊猫人啊  阅读(1629)  评论(0)    收藏  举报