前言
Httpclient 3.X和Httpclient 4.X如何请求HTTPS链接呢?由于网络安全性逐步提高,HTTPS链接已经慢慢在网络中盛行起来,特别一些大型网站,或者涉及到支付,交易的网站,都会使用HTTPS安全链接来提高网站的安全性。那么Java HttpClient如何请求HTTPS的链接呢? 这个是 Java爬虫肯定会遇到的一种问题,下面就针对请求HTTPS链接的方法,在下面逐一介绍。
Httpclient 3.X和Httpclient 4.X的版本差距比较大,请求HTTPS的方式各不一样.
HttpClient httpClient = null; Protocol myhttps = new Protocol("https", new MySecureProtocolSocketFactory(), 443); // 注册刚才创建的https 协议对象 Protocol.registerProtocol("https", myhttps); httpClient = new HttpClient(); httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000); httpClient.getHttpConnectionManager().getParams().setSoTimeout(5000); httpClient.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
新建MySecureProtocolSocketFactory.java类: /** * MySecureProtocolSocketFactory.java.java Create on 2012-9-26下午1:15:03 * * * Copyright (c) 2012 by MTA. * * @author lmeteor * @Email txin0814@sina.com * @description 自定义的socket factory 实现自动接受证书 * @version 1.0 */ public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory { private SSLContext sslcontext = null; private SSLContext createSSLContext() { SSLContext sslcontext = null; try { sslcontext = SSLContext.getInstance("SSL"); sslcontext.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom()); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } return sslcontext; } private SSLContext getSSLContext() { if (this.sslcontext == null) { this.sslcontext = createSSLContext(); } return this.sslcontext; } public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose); } public Socket createSocket(String host, int port) throws IOException, UnknownHostException { return getSSLContext().getSocketFactory().createSocket(host, port); } public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException, UnknownHostException { return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort); } public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params) throws IOException, UnknownHostException, ConnectTimeoutException { if (params == null) { throw new IllegalArgumentException("Parameters may not be null"); } int timeout = params.getConnectionTimeout(); SocketFactory socketfactory = getSSLContext().getSocketFactory(); if (timeout == 0) { return socketfactory.createSocket(host, port, localAddress, localPort); } else { Socket socket = socketfactory.createSocket(); SocketAddress localaddr = new InetSocketAddress(localAddress, localPort); SocketAddress remoteaddr = new InetSocketAddress(host, port); socket.bind(localaddr); socket.connect(remoteaddr, timeout); return socket; } } // 自定义私有类 private static class TrustAnyTrustManager implements X509TrustManager { public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[] {}; } } }
DefaultHttpClient httpClient = null ; DefaultHttpClient defaultClient; HttpParams httpParams = new BasicHttpParams(); ConnManagerParams.setMaxTotalConnections(httpParams, 80); ConnManagerParams.setTimeout(httpParams, 25000); //每个路由的最大链接个数,标志对同一站点的并发请求 ConnPerRouteBean connPerRoute = new ConnPerRouteBean(100); ConnManagerParams.setMaxConnectionsPerRoute(httpParams, connPerRoute); //设置允许请求HTTPS请求 SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); ClientConnectionManager connectionManager = new ThreadSafeClientConnManager(httpParams,registry); // httpParams.setParameter(ClientPNames.HANDLE_REDIRECTS,false); defaultClient = new DefaultHttpClient(connectionManager, httpParams); defaultClient.getParams().setIntParameter(HttpConnectionParams.SOCKET_BUFFER_SIZE, 20*1024); HttpClientParams.setCookiePolicy(defaultClient.getParams(),CookiePolicy.BROWSER_COMPATIBILITY); //defaultClient.getParams().setCookiePolicy(); //httpClient = defaultClient ; httpClient = WebClientDevWrapper.wrapClient(defaultClient);
//设置HTTPS SSL TLS X509请求的WebClientDevWrapper public static class WebClientDevWrapper { public static org.apache.http.impl.client.DefaultHttpClient wrapClient( org.apache.http.client.HttpClient base) { try { SSLContext ctx = SSLContext.getInstance("TLS"); //SSLContext.getInstance("SSL"); X509TrustManager tm = new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} public void checkClientTrusted( java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException { } public void checkServerTrusted( java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException { } }; ctx.init(null, new TrustManager[] { tm }, null); SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("https", 443, ssf)); registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(registry); return new DefaultHttpClient(mgr, base.getParams()); } catch (Exception ex) { ex.printStackTrace(); return null; } } }
下面给一个HttpClient请求HTTPS链接的例子,供大家参考:
/** * 0 没有使用 * 1 超级匿名 * 2 匿名 * 3 透明 * 4 没有使用 * * */ public class CheckHttpIP138 { public String check(){ boolean ret = false ; String rets = "" ; DefaultHttpClient client = null; if(client == null){ DefaultHttpClient defaultClient; HttpParams httpParams = new BasicHttpParams(); // HttpConnectionParams. ConnManagerParams.setMaxTotalConnections(httpParams, 80); ConnManagerParams.setTimeout(httpParams, 25000); //每个路由的最大链接个数,标志对同一站点的并发请求 ConnPerRouteBean connPerRoute = new ConnPerRouteBean(100); ConnManagerParams.setMaxConnectionsPerRoute(httpParams, connPerRoute); SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); ClientConnectionManager connectionManager = new ThreadSafeClientConnManager(httpParams,registry); // httpParams.setParameter(ClientPNames.HANDLE_REDIRECTS,false); defaultClient = new DefaultHttpClient(connectionManager, httpParams); defaultClient.getParams().setIntParameter(HttpConnectionParams.SOCKET_BUFFER_SIZE, 20*1024); HttpClientParams.setCookiePolicy(defaultClient.getParams(), CookiePolicy.BROWSER_COMPATIBILITY); //defaultClient.getParams().setCookiePolicy(); client = defaultClient ; } client.getParams().setIntParameter(HttpConnectionParams.SO_TIMEOUT,6000); // 超时设置 client.getParams().setIntParameter(HttpConnectionParams.CONNECTION_TIMEOUT, 6000);// 连接超时 //client.getParams().setIntParameter(HttpConnectionParams.s, 6000);// 连接超时 try { String url = "http://1111.ip138.com/ic.asp" ; HttpGet huid1 = new HttpGet(url); huid1.setHeader("Accept", "text/html, application/xhtml+xml, */*") ; huid1.setHeader("Accept-Language", "zh-CN") ; huid1.setHeader("Connection", "Keep-Alive") ; //huid1.setHeader("Referer", "http://www.sina.com.cn/") ; huid1.setHeader("Host", "1111.ip138.com") ; huid1.setHeader("Proxy-Connection", "Keep-Alive") ; huid1.setHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0; MALC)"); HttpResponse response2 = client.execute(huid1); //httpClient.executeMethod(g1) ; String sget1 = EntityUtils.toString(response2.getEntity(),"gbk"); int statusCode = response2.getStatusLine().getStatusCode(); if(statusCode==200 && sget1.indexOf("您的IP是")!=-1 ){ sget1 = sget1.substring(sget1.indexOf("您的IP是")) ; sget1 = sget1.substring(sget1.indexOf("[")+1) ; String ip = sget1.substring(0, sget1.indexOf("]")) ; rets = ip ; } }catch (Exception e) { System.out.println("判断http失败!"+e.toString()); } finally{ if(client !=null){ client.getConnectionManager().shutdown(); } } return rets ; } /** * 正常解决io流成字符串 * * @param entity * @throws IOException */ private String dump(HttpEntity entity, String encoding) { BufferedReader br = null; StringBuilder sb = null; try { br = new BufferedReader(new InputStreamReader(entity.getContent(), encoding)); sb = new StringBuilder(); String temp = null; while ((temp = br.readLine()) != null) { sb.append(temp); } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } return sb.toString(); } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub CheckHttpIP138 ch = new CheckHttpIP138() ; String rets =ch.check() ; System.out.println(rets) ; } }
注明: 代码中的网站均为例子,仅供参考,不一定真实有效额,请勿全部Copy。