HttpClient的ssl方式发送请求

最近因为项目需要,需要以rest方式和第三方平台交互,由于需要ssl方式连接,所以记录一下:

maven依赖如下:

        <dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>4.5.3</version>
		</dependency>

这里介绍两种ssl连接方式,一种是ssl信任所有的证书(基本上也就是没有安全性保证),另一种是ssl的正常使用(需要证书认证的)
首先是一个工具类


2019/4/3补充,前段时间,部署到生产环境后发生了一点问题,观察服务器日志(websphere)发现是报告线程挂起,通过查询google,发现是因为建立http连接后,没有关闭资源 ,造成资源耗尽,今天重新编辑此文

主要 增加了资源池对象 HttpClientConnectionManager

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager;

public class HttpsTrustManager implements X509TrustManager {

	@Override
	public void checkClientTrusted(X509Certificate[] arg0, String arg1)
			throws CertificateException {
		// TODO Auto-generated method stub

	}

	@Override
	public void checkServerTrusted(X509Certificate[] arg0, String arg1)
			throws CertificateException {
		// TODO Auto-generated method stub

	}

	@Override
	public X509Certificate[] getAcceptedIssuers() {
		return new X509Certificate[]{};
	}

}

正常SSL方式(需要证书)的工厂类

package com.haitaiinc.orionmonitor.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.util.Map;

import javax.net.ssl.SSLContext;

import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
/**
 * 构建httpclient的
 * @author Think
 *
 */
public class HttpClientFactory {

	
		
	private static CloseableHttpClient client;
	//连接池 
	private static  HttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager();
	
	
	  /**
     * 获取需要安全认证的httpClient的实例
     * @Title: getHttpsClient 
     * @Description: TODO
     * @Author: Think
     * @Date :Jan 16, 2019
     * @return: HttpClient
     */
    public static CloseableHttpClient getHttpsClient() throws Exception {

        if (client != null) {
            return client;
        }
        SSLContext sslcontext = getSSLContext();
        SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext,
                SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        
        client = HttpClients.custom().setConnectionManager(poolingConnManager).setSSLSocketFactory(factory).build();

        return client;
    }

    private static SSLContext getSSLContext() throws KeyStoreException, 
    NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException {
        KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());
        
        Map<String, String> map = ParseSSLUtil.getInterfaceConfig();
        String keyLocation = map.get("keystore");
        
        FileInputStream instream = new FileInputStream(new File(keyLocation));
        try {
            trustStore.load(instream, "changeit".toCharArray());
        } finally {
            instream.close();
        }
        return SSLContexts.custom()
                .loadTrustMaterial(trustStore)
                .build();
    }
    
    public static void releaseInstance() {
        client = null;
    }
    
    
}


不安全的SSL方式的工厂类

package com.haitaiinc.orionmonitor.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;

import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;

import org.apache.http.client.HttpClient;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

public class HttpClientFactoryWithNoSSL {

	private static CloseableHttpClient client;
	
	
	//连接池 
	private static  HttpClientConnectionManager poolingConnManager = new PoolingHttpClientConnectionManager();
    /**
	 * 获取不需要ssl认证的httpClient实例
	 * @Title: getHttpsClientWithNoCert 
	 * @Description: TODO
	 * @Author: Think
	 * @Date :Jan 16, 2019
	 * @return: HttpClient
	 */
    public static HttpClient getHttpsClient() throws Exception {

        if (client != null) {
            return client;
        }
        SSLContext sslcontext = SSLContexts.custom().useSSL().build();
        sslcontext.init(null, new X509TrustManager[]{new HttpsTrustManager()}, new SecureRandom());
        SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext,
                SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        client = HttpClients.custom().setConnectionManager(poolingConnManager).setSSLSocketFactory(factory).build();

        return client;
    }

    public static void releaseInstance() {
        client = null;
    }
}


使用样例:

     
    	

        //获取httpclient客户端
    	CloseableHttpClient httpsClient = HttpClientFactory.getHttpsClient();
    	//因为需要认证就是需要将{用户名:密码}变成字节数组并base64编码
		byte[] admin= ParseSSLUtil.getUserTokenString().getBytes();
		String encoding = ParseSSLUtil.encodeBase64(admin);
		
		//内存使用情况
		HttpGet httpGet = new HttpGet(config.get("url").concat("/api/statistics/memoryusage"));
		
		httpGet.addHeader("Content-Type", "application/json");
		httpGet.setHeader("Authorization", "Basic " + encoding);
		String mem = "";
		CloseableHttpResponse responseMem = null;
		CloseableHttpResponse responseCPU = null;
		CloseableHttpResponse responseDisk = null;
		try {
			responseMem = httpsClient.execute(httpGet);
			if(responseMem.getStatusLine().getStatusCode()!=HttpStatus.SC_OK){
				mem = "0";
			}else{
				HttpEntity entity = responseMem.getEntity();
				if(entity != null){
		            mem = EntityUtils.toString(entity,"UTF-8");
		        }
				EntityUtils.consume(entity);//要消耗消息实体,这是必须步骤
			}
		} catch (Exception e1) {
			e1.printStackTrace();
			mem = "0";
		}finally{
			responseMem.close();//尝试关闭资源,将socket连接返回给资源池
		}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
HttpClient是一个用于发送HTTP请求的开源框架,可以通过它发送GET、POST、PUT、DELETE等各种类型的请求。 如果需要使用HttpClient发送HTTPS的POST请求,需要对HttpClient进行配置,以确保安全性。 首先,需要创建一个SSL连接,用于发送HTTPS请求。可以通过创建一个SSL连接工厂来实现,这个工厂会使用信任的CA证书来验证目标服务器的身份。 接下来,创建一个HttpClient实例,并设置SSL连接工厂。 然后,创建一个HttpPost对象,设置请求的URL和请求参数。 接着,设置请求头,包括标识请求类型为POST、设置Content-Type为application/x-www-form-urlencoded等。 最后,使用HttpClient的execute方法执行POST请求,并获取返回的响应。 下面是一个示例代码: ``` import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.ssl.TrustStrategy; import org.apache.http.util.EntityUtils; import javax.net.ssl.SSLContext; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; public class HttpsPostExample { public static void main(String[] args) throws Exception { // 创建SSL连接工厂 SSLContext sslContext = SSLContextBuilder.create() .loadTrustMaterial(new TrustStrategy() { public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { return true; // 所有证书都被信任 } }) .build(); // 创建HttpClient实例,并设置SSL连接工厂 CloseableHttpClient httpClient = HttpClients.custom() .setSSLContext(sslContext) .build(); // 创建HttpPost对象,并设置URL和请求参数 HttpPost httpPost = new HttpPost("https://example.com"); String requestBody = "param1=value1&param2=value2"; httpPost.setEntity(new StringEntity(requestBody)); // 设置请求头 httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded"); // 发送POST请求,并获取响应 CloseableHttpResponse response = httpClient.execute(httpPost); String responseBody = EntityUtils.toString(response.getEntity()); // 输出响应结果 System.out.println(responseBody); // 关闭连接 response.close(); httpClient.close(); } } ``` 以上就是使用HttpClient发送HTTPS的POST请求的方法。通过SSL连接工厂的设置,可以确保请求的安全性。在实际使用中,可以根据需要设置请求参数、请求头等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值