HttpClent调用Https请求时报错

该博客介绍了如何处理使用HttpClinet进行HTTPS请求时遇到的SSLHandshakeException,通过创建共享连接池和定制SSL安全连接来解决问题。主要步骤包括设置连接池、创建SSLContext并忽略证书验证,确保支持多种TLS协议。同时,强调了使用共享连接池时不应关闭HttpClient以避免后续异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HttpClent调用https请求时报错:javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sum.security.provider.certpath.SunCertPathBuilderException: unable to find valid…
在这里插入图片描述
解决方案:
创建一个共享连接池

static {
		Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
				.register("http", PlainConnectionSocketFactory.INSTANCE)
				.register("https", createSSLConnSocketFactory())
				.build();
		// 设置连接池
		connMgr = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
		// 设置连接池大小
		connMgr.setMaxTotal(500);
		connMgr.setDefaultMaxPerRoute(connMgr.getMaxTotal());
		RequestConfig.Builder configBuilder = RequestConfig.custom();
		// 设置连接超时
		configBuilder.setConnectTimeout(MAX_TIMEOUT);
		// 设置读取超时
		configBuilder.setSocketTimeout(MAX_TIMEOUT);
		// 设置从连接池获取连接实例的超时
		configBuilder.setConnectionRequestTimeout(MAX_TIMEOUT);
		// 在提交请求之前 测试连接是否可用
		configBuilder.setStaleConnectionCheckEnabled(true);
		requestConfig = configBuilder.build();
	}

创建SSL安全连接,并指定允许的协议类型

/**
	 * 创建SSL安全连接
	 *
	 * @return
	 */
	private static SSLConnectionSocketFactory createSSLConnSocketFactory() {
		SSLConnectionSocketFactory sslsf = null;
		try {
			SSLContext ctx = SSLContext.getInstance("TLSv1.2");
			X509TrustManager tm = new X509TrustManager() {
				@Override
				public void checkClientTrusted(X509Certificate[] chain,
											   String authType) throws CertificateException {
				}

				@Override
				public void checkServerTrusted(X509Certificate[] chain,
											   String authType) throws CertificateException {
				}

				@Override
				public X509Certificate[] getAcceptedIssuers() {
					return null;
				}
			};
			ctx.init(null, new TrustManager[]{tm}, null);
			sslsf = new SSLConnectionSocketFactory(ctx, new String[] { "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" }, null,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
		} catch (GeneralSecurityException e) {
			e.printStackTrace();
		}
		return sslsf;
	}

注意使用共享链接池时,不能对httpClient进行close或者shutDown操作,否则下次使用连接池会抛出异常
在这里插入图片描述

public static String get(String url, Map<String,String> params, String charset){
		CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(connMgr).setDefaultRequestConfig(requestConfig).build();

			HttpGet hg = new HttpGet(url);

			try {
				responseStr = (String)httpclient.execute(hg, responseHandler);
			} catch (ClientProtocolException e) {
				logger.error("客户端连接协议错误", e);
			} catch (Exception e) {
				logger.error("IO操作异常", e);
			} /*finally {
			// 使用共享链接池的情况,不能关闭连接
			abortConnection(hg, httpclient);
			}*/
			return responseStr;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值