shikeying
2024-01-11 3b67e947e36133e2a40eb2737b15ea375e157ea0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package com.walker.web;
 
import com.walker.infrastructure.ApplicationRuntimeException;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
 
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;
 
/**
 * RestTemplate工厂创建对象。
 * @author 时克英
 * @date 2023-08-16
 */
public class RestTemplateFactory {
 
    public static final RestTemplate createRestTemplate(HttpType httpType, RestTemplateConfig config){
        if(config == null || httpType == null){
            throw new IllegalArgumentException("请提供参数");
        }
        if(httpType == HttpType.OkHttp){
            try {
                return acquireHttpOkRestTemplate(config.getMaxIdleConnections(), config.getKeepAliveDurationSeconds()
                        , config.getConnectTimeoutSeconds(), config.getReadTimeoutSeconds(), config.getWriteTimeoutSeconds());
            } catch (Exception e) {
                throw new ApplicationRuntimeException("创建:RestTemplate失败, " + e.getMessage(), e);
            }
        } else {
            throw new UnsupportedOperationException("未实现其他方式http连接");
        }
    }
 
    private static RestTemplate acquireHttpOkRestTemplate(int maxIdleConnections
            , long keepAliveDuration, long connectTimeout, long readTimeout, long writeTimeout) throws Exception{
        ConnectionPool connectionPool = new ConnectionPool(maxIdleConnections, keepAliveDuration, TimeUnit.SECONDS);
        OkHttpClient client = new OkHttpClient().newBuilder()
                .connectionPool(connectionPool)
                .connectTimeout(connectTimeout, TimeUnit.SECONDS)
                .readTimeout(readTimeout, TimeUnit.SECONDS)
                .writeTimeout(writeTimeout, TimeUnit.SECONDS)
//                .hostnameVerifier((hostname, session) -> true)
                .sslSocketFactory(getIgnoreInitSslContext().getSocketFactory(), IGNORE_SSL_TRUST_MANAGER_X509)
                .hostnameVerifier(getIgnoreSslHostnameVerifier())   // ssl相关,忽略否则https调用报证书错误
                // 设置代理
//              .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8888)))
                // 拦截器
//                .addInterceptor()
                .build();
 
        ClientHttpRequestFactory factory = new OkHttp3ClientHttpRequestFactory(client);
        RestTemplate restTemplate = new RestTemplate(factory);
        setupRestTemplate(restTemplate);
        return restTemplate;
    }
 
    private static void setupRestTemplate(RestTemplate restTemplate){
        List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
        Iterator<HttpMessageConverter<?>> iterator = messageConverters.iterator();
        while(iterator.hasNext()){
            HttpMessageConverter<?> converter=iterator.next();
            //原有的String是ISO-8859-1编码 去掉
            if(converter instanceof StringHttpMessageConverter){
                iterator.remove();
            }
        }
        messageConverters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
    }
 
    /**
     * Get initialized SSLContext instance which ignored SSL certification
     *
     * @return
     * @throws NoSuchAlgorithmException
     * @throws KeyManagementException
     */
    public static SSLContext getIgnoreInitSslContext() throws NoSuchAlgorithmException, KeyManagementException {
        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, new TrustManager[] { IGNORE_SSL_TRUST_MANAGER_X509 }, new SecureRandom());
        return sslContext;
    }
 
    /**
     * X509TrustManager instance which ignored SSL certification
     */
    public static final X509TrustManager IGNORE_SSL_TRUST_MANAGER_X509 = new X509TrustManager() {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) {
        }
 
        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) {
        }
 
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[] {};
        }
    };
 
    public static HostnameVerifier getIgnoreSslHostnameVerifier() {
        return new HostnameVerifier() {
            @Override
            public boolean verify(String arg0, SSLSession arg1) {
                return true;
            }
        };
    }
 
    public enum HttpType{
        OkHttp,
        HttpClient;
    }
 
//    public class Config{
//
//        public int getMaxIdleConnections() {
//            return maxIdleConnections;
//        }
//
//        public void setMaxIdleConnections(int maxIdleConnections) {
//            this.maxIdleConnections = maxIdleConnections;
//        }
//
//        public long getKeepAliveDurationSeconds() {
//            return keepAliveDurationSeconds;
//        }
//
//        public void setKeepAliveDurationSeconds(long keepAliveDurationSeconds) {
//            this.keepAliveDurationSeconds = keepAliveDurationSeconds;
//        }
//
//        public long getConnectTimeoutSeconds() {
//            return connectTimeoutSeconds;
//        }
//
//        public void setConnectTimeoutSeconds(long connectTimeoutSeconds) {
//            this.connectTimeoutSeconds = connectTimeoutSeconds;
//        }
//
//        public long getReadTimeoutSeconds() {
//            return readTimeoutSeconds;
//        }
//
//        public void setReadTimeoutSeconds(long readTimeoutSeconds) {
//            this.readTimeoutSeconds = readTimeoutSeconds;
//        }
//
//        public long getWriteTimeoutSeconds() {
//            return writeTimeoutSeconds;
//        }
//
//        public void setWriteTimeoutSeconds(long writeTimeoutSeconds) {
//            this.writeTimeoutSeconds = writeTimeoutSeconds;
//        }
//
//        // 连接池中整体的空闲连接的最大数量
//        private int maxIdleConnections = 100;
//        // 连接空闲时间最多为 300 秒
//        private long keepAliveDurationSeconds = 300;
//        // 连接超时(秒)
//        private long connectTimeoutSeconds = 3;
//        // 读超时(秒)
//        private long readTimeoutSeconds = 3;
//        // 写超时(秒)
//        private long writeTimeoutSeconds = 3;
//    }
}