HttpClient请求HTTPS报错javax.net.ssl.SSLException: hostname in certificate didn't match

首先写getSslsf()方法:    
private static SSLConnectionSocketFactory getSslsf() throws NoSuchAlgorithmException, KeyManagementException {
    	SSLContext sslContext = SSLContext.getInstance("SSL");//sslContext= SSLContext.getInstance("TLS");
	    X509TrustManager tm = new X509TrustManager() {  
	        
            public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {  

            }  

            public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {  
            }  

            public X509Certificate[] getAcceptedIssuers() {  
                return null;  
            }  
        };  
        sslContext.init(null, new TrustManager[] { tm }, null);
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        /*Registry<ConnectionSocketFactory> reg = RegistryBuilder.<ConnectionSocketFactory> create()
        		 .register("http", PlainConnectionSocketFactory.INSTANCE).register("https", sslsf).build();
        */
        return sslsf;
	}
再次创建HttpClients.custom().setSSLSocketFactory(getSslsf()).build()的httpClient;
CloseableHttpClient httpClient = null;
		HttpPost httpPost = null;
		try {
			
			httpClient = HttpClients.custom().setSSLSocketFactory(getSslsf()).build();//实例化HttpClients对象
			RequestConfig requestConfig = RequestConfig.custom()
					.setSocketTimeout(20000).setConnectTimeout(20000).build();//构建RequestConfig对象
			httpPost = new HttpPost(url);//构建HttpPost对象
			httpPost.setConfig(requestConfig);//设置RequestConfig
			/**
			 * 在请求正文中,可以随意的提交一段字符串给服务器,现在为了数据交换的统一性,所以大家都是提交的一段json串
			 * 所以body的数据格式{"name":"zhangsan","age":18},如果body是该数据格式,则Content-Type要设置为application/json
			 * new StringEntity(body)是指利用body构建一个请求正文对象,且StringEntity是支持Content-Type为application/json的,
			 * 所以,如果用StringEntity对象且body的数据为json串,则无需我们再设置Content-type
			 */
	        httpPost.setHeader("Content-Type","application/json");//setHeader是设置请求头,该句代码是设置Content-Type,要设置其它的请求头,也是setHeader方法
	        httpPost.setHeader("Connection","keep-alive");
	        httpPost.setEntity(new StringEntity(body));//设置请求正文,也就是设置json串
//			httpPost.setEntity(new StringEntity(body,"application/x-www-form-urlencoded"));//同上面两句代码一个意思
	        //SSLSocketFactory.getSocketFactory().setHostnameVerifier(new AllowAllHostnameVerifier());
	        //SSLConnectionSocketFactory sslFactory = new SSLConnectionSocketFactory(sslContext,SSLConnectionSocktFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
			CloseableHttpResponse response = httpClient.execute(httpPost);
			HttpEntity httpEntity = response.getEntity();//获取响应正文对象
			String result = EntityUtils.toString(httpEntity,"utf-8");
			System.out.println("***"+result);
			return result;//按编码输出响应正文
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(httpPost !=null){
					httpPost.releaseConnection();
				}
				if(httpClient !=null){
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;





对于使用 RestTemplate 发起 HTTPS 请求时忽略 SSL 证书验证,你可以通过创建自定义的 HttpClient 来实现。下面是一个示例: ```java import org.springframework.http.HttpMethod; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RequestCallback; import org.springframework.web.client.ResponseExtractor; import org.springframework.web.client.RestTemplate; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; public class SSLIgnoreRestTemplate extends RestTemplate { public SSLIgnoreRestTemplate() { super(); initialize(); } public SSLIgnoreRestTemplate(HttpComponentsClientHttpRequestFactory requestFactory) { super(requestFactory); initialize(); } private void initialize() { try { // 创建信任所有证书的 SSLContext SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[]{new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } }}, null); // 创建忽略 SSL 证书验证的 HttpClient HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); requestFactory.setHttpClient(HttpClients.custom().setSSLContext(sslContext) .setSSLHostnameVerifier((hostname, session) -> true).build()); setRequestFactory(requestFactory); } catch (Exception e) { throw new RuntimeException("Failed to initialize SSLIgnoreRestTemplate", e); } } // 如果有其他需要扩展的方法,可以在这里进行覆盖 @Override public <T> T execute(String url, HttpMethod method, RequestCallback requestCallback, ResponseExtractor<T> responseExtractor, Object... uriVariables) { return super.execute(url, method, requestCallback, responseExtractor, uriVariables); } // ... } ``` 使用时,你可以像使用普通的 RestTemplate 一样进行请求。这个自定义的 RestTemplate 将会忽略 SSL 证书验证。例如: ```java RestTemplate restTemplate = new SSLIgnoreRestTemplate(); ResponseEntity<String> response = restTemplate.exchange("https://your-url.com", HttpMethod.GET, null, String.class); ``` 需要注意的是,忽略 SSL 证书验证存在安全风险,因此建议仅在开发和测试环境中使用,并不推荐在生产环境中使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值