HttpRequest.java 15.1 KB
Newer Older
如梦技术's avatar
如梦技术 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 * Copyright (c) 2019-2029, Dreamlu (596392912@qq.com & www.dreamlu.net).
 * <p>
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/lgpl.html
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

17
package net.dreamlu.mica.http;
如梦技术's avatar
如梦技术 已提交
18

如梦技术's avatar
如梦技术 已提交
19 20 21 22
import net.dreamlu.mica.core.ssl.DisableValidationTrustManager;
import net.dreamlu.mica.core.ssl.TrustAllHostNames;
import net.dreamlu.mica.core.utils.Exceptions;
import net.dreamlu.mica.core.utils.Holder;
如梦技术's avatar
如梦技术 已提交
23
import net.dreamlu.mica.core.utils.JsonUtil;
如梦技术's avatar
如梦技术 已提交
24
import net.dreamlu.mica.core.utils.StringPool;
如梦技术's avatar
如梦技术 已提交
25
import okhttp3.*;
26
import okhttp3.internal.Util;
如梦技术's avatar
如梦技术 已提交
27 28 29
import okhttp3.internal.http.HttpMethod;
import okhttp3.logging.HttpLoggingInterceptor;

30
import javax.annotation.Nullable;
如梦技术's avatar
如梦技术 已提交
31
import javax.net.ssl.*;
如梦技术's avatar
如梦技术 已提交
32
import java.io.IOException;
如梦技术's avatar
如梦技术 已提交
33
import java.net.InetSocketAddress;
如梦技术's avatar
如梦技术 已提交
34
import java.net.Proxy;
如梦技术's avatar
如梦技术 已提交
35
import java.net.ProxySelector;
如梦技术's avatar
如梦技术 已提交
36
import java.net.URI;
如梦技术's avatar
如梦技术 已提交
37 38
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
如梦技术's avatar
如梦技术 已提交
39
import java.time.Duration;
40 41
import java.util.ArrayList;
import java.util.List;
42
import java.util.Map;
43
import java.util.Optional;
如梦技术's avatar
如梦技术 已提交
44
import java.util.concurrent.TimeUnit;
45 46 47
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
48
import java.util.function.Predicate;
如梦技术's avatar
如梦技术 已提交
49 50 51 52 53 54

/**
 * ok http 封装,请求结构体
 *
 * @author L.cm
 */
55
public class HttpRequest {
如梦技术's avatar
如梦技术 已提交
56
	private static final String DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36";
如梦技术's avatar
如梦技术 已提交
57
	private static volatile OkHttpClient httpClient = new OkHttpClient();
58
	@Nullable
59
	private static HttpLoggingInterceptor globalLoggingInterceptor = null;
如梦技术's avatar
如梦技术 已提交
60
	private final Request.Builder requestBuilder;
61
	private final HttpUrl.Builder uriBuilder;
如梦技术's avatar
如梦技术 已提交
62 63
	private final String httpMethod;
	private String userAgent;
64
	@Nullable
如梦技术's avatar
如梦技术 已提交
65
	private RequestBody requestBody;
66
	@Nullable
如梦技术's avatar
如梦技术 已提交
67
	private Boolean followRedirects;
68
	@Nullable
69
	private Boolean followSslRedirects;
70
	@Nullable
如梦技术's avatar
如梦技术 已提交
71
	private HttpLoggingInterceptor.Level level;
72
	@Nullable
73
	private CookieJar cookieJar;
74
	@Nullable
75
	private EventListener eventListener;
76
	private final List<Interceptor> interceptors = new ArrayList<>();
77
	@Nullable
78
	private Authenticator authenticator;
79
	@Nullable
如梦技术's avatar
如梦技术 已提交
80
	private Duration connectTimeout;
81
	@Nullable
如梦技术's avatar
如梦技术 已提交
82
	private Duration readTimeout;
83
	@Nullable
如梦技术's avatar
如梦技术 已提交
84
	private Duration writeTimeout;
85
	@Nullable
如梦技术's avatar
如梦技术 已提交
86
	private Proxy proxy;
87
	@Nullable
如梦技术's avatar
如梦技术 已提交
88
	private ProxySelector proxySelector;
89
	@Nullable
如梦技术's avatar
如梦技术 已提交
90
	private Authenticator proxyAuthenticator;
91 92 93
	@Nullable
	private RetryPolicy retryPolicy;
	@Nullable
如梦技术's avatar
如梦技术 已提交
94 95
	private Boolean disableSslValidation;
	@Nullable
如梦技术's avatar
如梦技术 已提交
96
	private HostnameVerifier hostnameVerifier;
97
	@Nullable
如梦技术's avatar
如梦技术 已提交
98
	private SSLSocketFactory sslSocketFactory;
99
	@Nullable
如梦技术's avatar
如梦技术 已提交
100
	private X509TrustManager trustManager;
101
	private BiConsumer<Request, IOException> failedBiConsumer = (r, e) -> {};
如梦技术's avatar
如梦技术 已提交
102

103
	public static HttpRequest get(final String url) {
如梦技术's avatar
如梦技术 已提交
104
		return new HttpRequest(new Request.Builder(), url, Method.GET);
如梦技术's avatar
如梦技术 已提交
105 106
	}

107
	public static HttpRequest get(final URI uri) {
如梦技术's avatar
如梦技术 已提交
108
		return get(uri.toString());
如梦技术's avatar
如梦技术 已提交
109 110
	}

111
	public static HttpRequest post(final String url) {
如梦技术's avatar
如梦技术 已提交
112
		return new HttpRequest(new Request.Builder(), url, Method.POST);
如梦技术's avatar
如梦技术 已提交
113 114
	}

115
	public static HttpRequest post(final URI uri) {
如梦技术's avatar
如梦技术 已提交
116
		return post(uri.toString());
如梦技术's avatar
如梦技术 已提交
117 118
	}

119
	public static HttpRequest patch(final String url) {
如梦技术's avatar
如梦技术 已提交
120
		return new HttpRequest(new Request.Builder(), url, Method.PATCH);
如梦技术's avatar
如梦技术 已提交
121 122
	}

123
	public static HttpRequest patch(final URI uri) {
如梦技术's avatar
如梦技术 已提交
124
		return patch(uri.toString());
如梦技术's avatar
如梦技术 已提交
125 126
	}

127
	public static HttpRequest put(final String url) {
如梦技术's avatar
如梦技术 已提交
128
		return new HttpRequest(new Request.Builder(), url, Method.PUT);
如梦技术's avatar
如梦技术 已提交
129 130
	}

131
	public static HttpRequest put(final URI uri) {
如梦技术's avatar
如梦技术 已提交
132
		return put(uri.toString());
如梦技术's avatar
如梦技术 已提交
133 134
	}

135
	public static HttpRequest delete(final String url) {
如梦技术's avatar
如梦技术 已提交
136
		return new HttpRequest(new Request.Builder(), url, Method.DELETE);
如梦技术's avatar
如梦技术 已提交
137 138
	}

139
	public static HttpRequest delete(final URI uri) {
如梦技术's avatar
如梦技术 已提交
140
		return delete(uri.toString());
如梦技术's avatar
如梦技术 已提交
141 142
	}

143 144
	public HttpRequest query(String query) {
		this.uriBuilder.query(query);
如梦技术's avatar
如梦技术 已提交
145 146 147
		return this;
	}

如梦技术's avatar
如梦技术 已提交
148
	public HttpRequest queryEncoded(String encodedQuery) {
149 150 151 152
		this.uriBuilder.encodedQuery(encodedQuery);
		return this;
	}

153
	public HttpRequest queryMap(@Nullable Map<String, Object> queryMap) {
154 155 156 157 158 159
		if (queryMap != null && !queryMap.isEmpty()) {
			queryMap.forEach(this::query);
		}
		return this;
	}

如梦技术's avatar
如梦技术 已提交
160
	public HttpRequest query(String name, @Nullable Object value) {
161 162 163 164
		this.uriBuilder.addQueryParameter(name, value == null ? null : String.valueOf(value));
		return this;
	}

如梦技术's avatar
如梦技术 已提交
165 166
	public HttpRequest queryEncoded(String encodedName, @Nullable Object encodedValue) {
		this.uriBuilder.addEncodedQueryParameter(encodedName, encodedValue == null ? null : String.valueOf(encodedValue));
如梦技术's avatar
如梦技术 已提交
167 168 169
		return this;
	}

170
	HttpRequest form(FormBody formBody) {
如梦技术's avatar
如梦技术 已提交
171 172 173 174
		this.requestBody = formBody;
		return this;
	}

175
	HttpRequest multipartForm(MultipartBody multipartBody) {
如梦技术's avatar
如梦技术 已提交
176 177 178 179
		this.requestBody = multipartBody;
		return this;
	}

180 181
	public FormBuilder formBuilder() {
		return new FormBuilder(this);
如梦技术's avatar
如梦技术 已提交
182 183
	}

184 185
	public MultipartFormBuilder multipartFormBuilder() {
		return new MultipartFormBuilder(this);
如梦技术's avatar
如梦技术 已提交
186 187
	}

188
	public HttpRequest body(RequestBody requestBody) {
如梦技术's avatar
如梦技术 已提交
189 190 191 192
		this.requestBody = requestBody;
		return this;
	}

193
	public HttpRequest bodyString(String body) {
如梦技术's avatar
如梦技术 已提交
194 195 196 197
		this.requestBody = RequestBody.create(null, body);
		return this;
	}

198
	public HttpRequest bodyJson(Object body) {
如梦技术's avatar
如梦技术 已提交
199 200 201
		return bodyString(JsonUtil.toJson(body));
	}

如梦技术's avatar
如梦技术 已提交
202 203
	private HttpRequest(final Request.Builder requestBuilder, String url, String httpMethod) {
		HttpUrl httpUrl = HttpUrl.parse(url);
204 205 206
		if (httpUrl == null) {
			throw new IllegalArgumentException(String.format("Url 不能解析: %s: [%s]。", httpMethod.toLowerCase(), url));
		}
如梦技术's avatar
如梦技术 已提交
207
		this.requestBuilder = requestBuilder;
208
		this.uriBuilder = httpUrl.newBuilder();
如梦技术's avatar
如梦技术 已提交
209 210 211 212
		this.httpMethod = httpMethod;
		this.userAgent = DEFAULT_USER_AGENT;
	}

213
	private Call internalCall(final OkHttpClient client) {
如梦技术's avatar
如梦技术 已提交
214
		OkHttpClient.Builder builder = client.newBuilder();
215 216
		if (connectTimeout != null) {
			builder.connectTimeout(connectTimeout.toMillis(), TimeUnit.MILLISECONDS);
如梦技术's avatar
如梦技术 已提交
217
		}
218 219
		if (readTimeout != null) {
			builder.readTimeout(readTimeout.toMillis(), TimeUnit.MILLISECONDS);
如梦技术's avatar
如梦技术 已提交
220
		}
221 222
		if (writeTimeout != null) {
			builder.writeTimeout(writeTimeout.toMillis(), TimeUnit.MILLISECONDS);
如梦技术's avatar
如梦技术 已提交
223
		}
224 225
		if (proxy != null) {
			builder.proxy(proxy);
如梦技术's avatar
如梦技术 已提交
226
		}
227 228
		if (proxySelector != null) {
			builder.proxySelector(proxySelector);
如梦技术's avatar
如梦技术 已提交
229
		}
230
		if (proxyAuthenticator != null) {
如梦技术's avatar
如梦技术 已提交
231 232
			builder.proxyAuthenticator(proxyAuthenticator);
		}
233
		if (hostnameVerifier != null) {
如梦技术's avatar
如梦技术 已提交
234 235
			builder.hostnameVerifier(hostnameVerifier);
		}
236
		if (sslSocketFactory != null && trustManager != null) {
如梦技术's avatar
如梦技术 已提交
237 238
			builder.sslSocketFactory(sslSocketFactory, trustManager);
		}
如梦技术's avatar
如梦技术 已提交
239 240 241
		if (Boolean.TRUE.equals(disableSslValidation)) {
			disableSslValidation(builder);
		}
242
		if (authenticator != null) {
243 244
			builder.authenticator(authenticator);
		}
245 246
		if (eventListener != null) {
			builder.eventListener(eventListener);
如梦技术's avatar
如梦技术 已提交
247
		}
248 249 250 251
		if (!interceptors.isEmpty()) {
			builder.interceptors().addAll(interceptors);
		}
		if (cookieJar != null) {
252 253
			builder.cookieJar(cookieJar);
		}
254 255
		if (followRedirects != null) {
			builder.followRedirects(followRedirects);
256
		}
257 258
		if (followSslRedirects != null) {
			builder.followSslRedirects(followSslRedirects);
如梦技术's avatar
如梦技术 已提交
259
		}
260 261 262
		if (retryPolicy != null) {
			builder.addInterceptor(new RetryInterceptor(retryPolicy));
		}
263
		if (level != null && HttpLoggingInterceptor.Level.NONE != level) {
264 265 266 267
			builder.addInterceptor(getLoggingInterceptor(level));
		} else if (globalLoggingInterceptor != null) {
			builder.addInterceptor(globalLoggingInterceptor);
		}
如梦技术's avatar
如梦技术 已提交
268
		// 设置 User-Agent
269
		requestBuilder.header("User-Agent", userAgent);
如梦技术's avatar
如梦技术 已提交
270
		// url
271
		requestBuilder.url(uriBuilder.build());
272
		String method = httpMethod;
如梦技术's avatar
如梦技术 已提交
273 274
		Request request;
		if (HttpMethod.requiresRequestBody(method) && requestBody == null) {
275
			request = requestBuilder.method(method, Util.EMPTY_REQUEST).build();
如梦技术's avatar
如梦技术 已提交
276
		} else {
277
			request = requestBuilder.method(method, requestBody).build();
如梦技术's avatar
如梦技术 已提交
278
		}
279
		return builder.build().newCall(request);
如梦技术's avatar
如梦技术 已提交
280 281
	}

282
	public <R> R onResponse(Function<ResponseSpec, R> func) {
283
		Call call = internalCall(httpClient);
284 285
		try (HttpResponse response = new HttpResponse(call.execute())) {
			return func.apply(response);
如梦技术's avatar
如梦技术 已提交
286
		} catch (IOException e) {
287 288 289 290 291 292 293 294 295
			return func.apply(new ErrorResponse(call.request(), e));
		}
	}

	@Nullable
	public <R> R onSuccess(Function<ResponseSpec, R> func) {
		Call call = internalCall(httpClient);
		try (HttpResponse response = new HttpResponse(call.execute())) {
			return func.apply(response);
296 297
		} catch (IOException e) {
			failedBiConsumer.accept(call.request(), e);
298
			return null;
如梦技术's avatar
如梦技术 已提交
299 300 301
		}
	}

302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
	@Nullable
	public <R> R onSuccessful(Function<ResponseSpec, R> func) {
		Call call = internalCall(httpClient);
		try (HttpResponse response = new HttpResponse(call.execute())) {
			if (response.isOk()) {
				return func.apply(response);
			} else {
				failedBiConsumer.accept(call.request(), new IOException(response.toString()));
			}
		} catch (IOException e) {
			failedBiConsumer.accept(call.request(), e);
		}
		return null;
	}

	public <R> Optional<R> onSuccessOpt(Function<ResponseSpec, R> func) {
		return Optional.ofNullable(this.onSuccess(func));
	}

	public <R> Optional<R> onSuccessfulOpt(Function<ResponseSpec, R> func) {
		return Optional.ofNullable(this.onSuccessful(func));
	}

	public HttpRequest onFailed(BiConsumer<Request, IOException> failConsumer) {
		this.failedBiConsumer = failConsumer;
		return this;
	}

330 331 332 333 334
	public AsyncCall async() {
		Call call = internalCall(httpClient);
		return new AsyncCall(call);
	}

335 336 337 338 339
	public HttpRequest baseAuth(String userName, String password) {
		this.authenticator = new BaseAuthenticator(userName, password);
		return this;
	}

如梦技术's avatar
如梦技术 已提交
340
	//// HTTP header operations
341 342 343 344 345 346
	public HttpRequest addHeader(final Map<String, String> headers) {
		this.requestBuilder.headers(Headers.of(headers));
		return this;
	}

	public HttpRequest addHeader(final String... namesAndValues) {
如梦技术's avatar
如梦技术 已提交
347 348 349 350 351
		Headers headers = Headers.of(namesAndValues);
		this.requestBuilder.headers(headers);
		return this;
	}

352
	public HttpRequest addHeader(final String name, final String value) {
如梦技术's avatar
如梦技术 已提交
353 354 355 356
		this.requestBuilder.addHeader(name, value);
		return this;
	}

357
	public HttpRequest setHeader(final String name, final String value) {
如梦技术's avatar
如梦技术 已提交
358 359 360 361
		this.requestBuilder.header(name, value);
		return this;
	}

362
	public HttpRequest removeHeader(final String name) {
如梦技术's avatar
如梦技术 已提交
363 364 365 366
		this.requestBuilder.removeHeader(name);
		return this;
	}

367 368 369 370 371
	public HttpRequest addCookie(final Cookie cookie) {
		this.addHeader("Cookie", cookie.toString());
		return this;
	}

372
	public HttpRequest cacheControl(final CacheControl cacheControl) {
如梦技术's avatar
如梦技术 已提交
373 374 375 376
		this.requestBuilder.cacheControl(cacheControl);
		return this;
	}

377
	public HttpRequest userAgent(final String userAgent) {
如梦技术's avatar
如梦技术 已提交
378 379 380 381
		this.userAgent = userAgent;
		return this;
	}

382
	public HttpRequest followRedirects(boolean followRedirects) {
如梦技术's avatar
如梦技术 已提交
383 384 385 386
		this.followRedirects = followRedirects;
		return this;
	}

387 388 389 390 391
	public HttpRequest followSslRedirects(boolean followSslRedirects) {
		this.followSslRedirects = followSslRedirects;
		return this;
	}

如梦技术's avatar
如梦技术 已提交
392 393 394 395 396 397
	private static HttpLoggingInterceptor getLoggingInterceptor(HttpLoggingInterceptor.Level level) {
		HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(Slf4jLogger.INSTANCE);
		loggingInterceptor.setLevel(level);
		return loggingInterceptor;
	}

398
	public HttpRequest log() {
如梦技术's avatar
如梦技术 已提交
399 400 401 402
		this.level = HttpLoggingInterceptor.Level.BODY;
		return this;
	}

如梦技术's avatar
如梦技术 已提交
403 404
	public HttpRequest log(LogLevel logLevel) {
		this.level = logLevel.getLevel();
如梦技术's avatar
如梦技术 已提交
405 406 407
		return this;
	}

408 409 410 411 412
	public HttpRequest authenticator(Authenticator authenticator) {
		this.authenticator = authenticator;
		return this;
	}

413 414 415 416 417
	public HttpRequest eventListener(EventListener eventListener) {
		this.eventListener = eventListener;
		return this;
	}

418
	public HttpRequest interceptor(Interceptor interceptor) {
419
		this.interceptors.add(interceptor);
如梦技术's avatar
如梦技术 已提交
420 421 422
		return this;
	}

423 424 425 426 427
	public HttpRequest cookieManager(CookieJar cookieJar) {
		this.cookieJar = cookieJar;
		return this;
	}

如梦技术's avatar
如梦技术 已提交
428
	//// HTTP connection parameter operations
429
	public HttpRequest connectTimeout(final Duration timeout) {
如梦技术's avatar
如梦技术 已提交
430 431 432 433
		this.connectTimeout = timeout;
		return this;
	}

434
	public HttpRequest readTimeout(Duration readTimeout) {
如梦技术's avatar
如梦技术 已提交
435 436 437 438
		this.readTimeout = readTimeout;
		return this;
	}

439
	public HttpRequest writeTimeout(Duration writeTimeout) {
如梦技术's avatar
如梦技术 已提交
440 441 442 443
		this.writeTimeout = writeTimeout;
		return this;
	}

如梦技术's avatar
如梦技术 已提交
444
	public HttpRequest proxy(final InetSocketAddress address) {
如梦技术's avatar
如梦技术 已提交
445
		this.proxy = new Proxy(Proxy.Type.HTTP, address);
如梦技术's avatar
如梦技术 已提交
446 447 448
		return this;
	}

如梦技术's avatar
如梦技术 已提交
449 450 451 452 453 454 455 456 457 458
	public HttpRequest proxySelector(final ProxySelector proxySelector) {
		this.proxySelector = proxySelector;
		return this;
	}

	public HttpRequest proxyAuthenticator(final Authenticator proxyAuthenticator) {
		this.proxyAuthenticator = proxyAuthenticator;
		return this;
	}

459 460 461 462 463
	public HttpRequest retry() {
		this.retryPolicy = RetryPolicy.INSTANCE;
		return this;
	}

464 465 466 467 468
	public HttpRequest retryOn(Predicate<ResponseSpec> respPredicate) {
		this.retryPolicy = new RetryPolicy(respPredicate);
		return this;
	}

469 470 471 472 473
	public HttpRequest retry(int maxAttempts, long sleepMillis) {
		this.retryPolicy = new RetryPolicy(maxAttempts, sleepMillis);
		return this;
	}

474 475 476 477 478
	public HttpRequest retry(int maxAttempts, long sleepMillis, Predicate<ResponseSpec> respPredicate) {
		this.retryPolicy = new RetryPolicy(maxAttempts, sleepMillis);
		return this;
	}

如梦技术's avatar
如梦技术 已提交
479 480 481 482 483 484 485 486 487 488
	/**
	 * 关闭 ssl 校验
	 *
	 * @return HttpRequest
	 */
	public HttpRequest disableSslValidation() {
		this.disableSslValidation = Boolean.TRUE;
		return this;
	}

如梦技术's avatar
如梦技术 已提交
489 490 491 492 493 494 495 496 497 498 499
	public HttpRequest hostnameVerifier(HostnameVerifier hostnameVerifier) {
		this.hostnameVerifier = hostnameVerifier;
		return this;
	}

	public HttpRequest sslSocketFactory(SSLSocketFactory sslSocketFactory, X509TrustManager trustManager) {
		this.sslSocketFactory = sslSocketFactory;
		this.trustManager = trustManager;
		return this;
	}

如梦技术's avatar
如梦技术 已提交
500 501 502 503 504 505
	@Override
	public String toString() {
		return requestBuilder.toString();
	}

	public static void setHttpClient(OkHttpClient httpClient) {
506
		HttpRequest.httpClient = httpClient;
如梦技术's avatar
如梦技术 已提交
507
	}
如梦技术's avatar
如梦技术 已提交
508 509 510 511

	public static void setGlobalLog(LogLevel logLevel) {
		HttpRequest.globalLoggingInterceptor = getLoggingInterceptor(logLevel.getLevel());
	}
如梦技术's avatar
如梦技术 已提交
512 513 514 515 516 517 518 519 520 521

	static String handleValue(@Nullable Object value) {
		if (value == null) {
			return StringPool.EMPTY;
		}
		if (value instanceof String) {
			return (String) value;
		}
		return String.valueOf(value);
	}
如梦技术's avatar
如梦技术 已提交
522 523 524 525 526 527 528 529 530 531 532 533 534 535

	private static void disableSslValidation(OkHttpClient.Builder builder) {
		try {
			X509TrustManager disabledTrustManager = DisableValidationTrustManager.INSTANCE;
			TrustManager[] trustManagers = new TrustManager[]{disabledTrustManager};
			SSLContext sslContext = SSLContext.getInstance("SSL");
			sslContext.init(null, trustManagers, Holder.SECURE_RANDOM);
			SSLSocketFactory disabledSslSocketFactory = sslContext.getSocketFactory();
			builder.sslSocketFactory(disabledSslSocketFactory, disabledTrustManager);
			builder.hostnameVerifier(TrustAllHostNames.INSTANCE);
		} catch (NoSuchAlgorithmException | KeyManagementException e) {
			throw Exceptions.unchecked(e);
		}
	}
如梦技术's avatar
如梦技术 已提交
536
}