Apache HttpClient 如何进行https连接

来源:互联网 发布:淘宝助理文件夹 编辑:程序博客网 时间:2024/04/28 09:41

HttpGet httpGet = new HttpGet("https://www.signpost.com/login");HttpClient client = new DefaultHttpClient();HttpResponse response = client.execute(httpGet);HttpEntity entity = response.getEntity();

在HttpClient,如果直接使用HttpGet 和DefaultHttpClient进行连接会报如下异常

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

这是因为HttpClient 进行https连接时需要一个合法的SSL Certificate

解决办法(http://javaskeleton.blogspot.com/2010/07/avoiding-peer-not-authenticated-with.html)

1. 创建一个新的自定义的信任管理:TrustManager,从而所有的Certificate

HttpClient client = new DefaultHttpClient();X509TrustManager tm = new X509TrustManager() {//在原始的TrustManger中,如果certificate是非法,则会抛出CertificateException //这里,无论是合法还是非法的,都不抛异常,跳过检查public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {} public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {} public X509Certificate[] getAcceptedIssuers() {return null;}};

2. 有了新的TrustManger后,需要添加到client中。 这里需要SSL sockets,这是HttpClient进行Https连接时,使用的Socket。

SSLContext ctx = SSLContext.getInstance("TLS");ctx.init(null, new TrustManager[]{tm}, null);SSLSocketFactory ssf = new SSLSocketFactory(ctx);//这里需要忽略掉HostName的比较,否则访问一些网站时,会报异常ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);


3. 利用新得到的SSLSocket,创建一个新的能进行Https访问的client

ClientConnectionManager ccm = client.getConnectionManager();SchemeRegistry sr = ccm.getSchemeRegistry();sr.register(new Scheme("https", ssf, 443));client = new DefaultHttpClient(ccm, client.getParams());

测试:
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.security.KeyManagementException;import java.security.NoSuchAlgorithmException;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;import javax.net.ssl.SSLContext;import javax.net.ssl.TrustManager;import javax.net.ssl.X509TrustManager;import org.apache.http.HttpEntity;import org.apache.http.HttpHost;import org.apache.http.HttpResponse;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpGet;import org.apache.http.conn.ClientConnectionManager;import org.apache.http.conn.params.ConnRoutePNames;import org.apache.http.conn.scheme.Scheme;import org.apache.http.conn.scheme.SchemeRegistry;import org.apache.http.conn.ssl.SSLSocketFactory;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.params.CoreConnectionPNames;public class HttpsClient {private static 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;}};@SuppressWarnings("deprecation")public static HttpClient getInstance() throws KeyManagementException,NoSuchAlgorithmException {HttpClient client = new DefaultHttpClient();SSLContext ctx = SSLContext.getInstance("TLS");ctx.init(null, new TrustManager[] { tm }, null);SSLSocketFactory ssf = new SSLSocketFactory(ctx);ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);ClientConnectionManager ccm = client.getConnectionManager();SchemeRegistry sr = ccm.getSchemeRegistry();sr.register(new Scheme("https", ssf, 443));client = new DefaultHttpClient(ccm, client.getParams());return client;}public static void main(String[] args) throws KeyManagementException,NoSuchAlgorithmException, IllegalStateException, IOException {HttpClient httpsClient = HttpsClient.getInstance();HttpHost proxy = new HttpHost("172.28.8.246", 8080);httpsClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,proxy);httpsClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,20000);HttpGet httpGet = new HttpGet("https://www.signpost.com/login");HttpResponse response = httpsClient.execute(httpGet);HttpEntity entity = response.getEntity();BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent()));StringBuffer content = new StringBuffer();for (String line; (line = br.readLine()) != null;) {content.append(line + "\r\n");}System.err.println(content.toString());}}

最后,注意一下导入的包,别混淆了

原创粉丝点击