前言
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。
【蝴蝶效应-虎】