并不是所有的https请求都需要按照下面的代码进行设置,如果遇到下面的问题,则需要这么做。

javax.net.ssl.SSLException: hostname in certificate didn’t match:

采用绕过验证的方式处理https请求

需要指定信任所有证书,并指定不校验域名。

DefaultHttpClient

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
public static DefaultHttpClient getHttpClient(String url, Proxy proxy)
			throws Exception {
    SSLSocketFactory sf = new SSLSocketFactory(new TrustStrategy() {
        // 信任所有
        @Override
        public boolean isTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException {
            return true;
        }
    });
    sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    // 连接池设置
    SchemeRegistry schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
    schemeRegistry.register(new Scheme("https", 443, sf));
    PoolingClientConnectionManager cm = new PoolingClientConnectionManager(schemeRegistry);
    cm.setMaxTotal(200); // 连接池里的最大连接数
    cm.setDefaultMaxPerRoute(20); // 每个路由的默认最大连接数
    // 其它设置
    DefaultHttpClient httpClient = new DefaultHttpClient(cm);
    CookieStore cookieStore = httpClient.getCookieStore();
    // 添加语言cookie
    BasicClientCookie2 langCookie = new BasicClientCookie2("LangKey", "cs");
    langCookie.setVersion(0);
    langCookie.setDomain(Utility.getPurceHost(url));
    langCookie.setPath("/");
    cookieStore.addCookie(langCookie);
    HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {
        public boolean retryRequest(IOException exception,
                                    int executionCount, HttpContext context) {
            if (executionCount >= 3) {
                // 如果超过最大重试次数,那么就不要继续了
                return false;
            }
            if (exception instanceof NoHttpResponseException) {
                // 如果服务器丢掉了连接,那么就重试
                return true;
            }
            if (exception instanceof SSLHandshakeException) {
                // 不要重试SSL握手异常
                return false;
            }
            HttpRequest request = (HttpRequest) context
                    .getAttribute(ExecutionContext.HTTP_REQUEST);
            boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
            if (idempotent) {
                // 如果请求被认为是幂等的,那么就重试
                return true;
            }
            return false;
        }
    };
    httpClient.setHttpRequestRetryHandler(myRetryHandler);
    // 设置读取超时时间
    httpClient.getParams().setIntParameter("http.socket.timeout",
            SnatchConstant.TIMEOUT);
    // 设置连接超时超时
    httpClient.getParams()
            .setIntParameter(HttpConnectionParams.CONNECTION_TIMEOUT,
                    SnatchConstant.TIMEOUT);
    // 添加代理
    if (null != proxy) {
        if (proxy.getUsed() == 1) {
            String ip = proxy.getIp();// 代理ip
            int port = proxy.getPort();// 代理端口
            String proxyUserName = proxy.getUsername();// 代理账号用户名
            String proxyPassword = proxy.getPassword();// 代理账号密码
            if (!(Utility.isNull(ip) || port <= 0)) {
                // 访问的目标站点,端口和协议
                httpClient.getCredentialsProvider().setCredentials(
                        new AuthScope(ip, port),
                        new UsernamePasswordCredentials(proxyUserName,
                                proxyPassword));
                // 代理的设置
                HttpHost proxyHost = new HttpHost(ip, port);
                httpClient.getParams().setParameter(
                        ConnRoutePNames.DEFAULT_PROXY, proxyHost);
            }
        }
    }
    return httpClient;
}

CloseableHttpClient

如果是CloseableHttpClient,可以使用下面的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public static CloseableHttpClient createSSLClientDefault(String url, Proxy proxy){
    try {
        CookieStore cookieStore = new BasicCookieStore();
        // 添加语言cookie
        BasicClientCookie2 langCookie = new BasicClientCookie2("LangKey", "cs");
        langCookie.setVersion(0);
        langCookie.setDomain(Utility.getPurceHost(url));
        langCookie.setPath("/");
        cookieStore.addCookie(langCookie);
        RequestConfig config = null;
        if (config == null) {
            config = RequestConfig.custom().setConnectTimeout(SnatchConstant.TIMEOUT).setSocketTimeout(SnatchConstant.TIMEOUT).build();
        }
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
            //信任所有
            @Override
            public boolean isTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException {
                return true;
            }
        }).build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);
        return HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultCookieStore(cookieStore).setDefaultRequestConfig(config).setRetryHandler((new HttpRequestRetryHandler() {
            @Override
            public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
                if (executionCount >= 3) {
                    // 如果超过最大重试次数,那么就不要继续了
                    return false;
                }
                if (exception instanceof NoHttpResponseException) {
                    // 如果服务器丢掉了连接,那么就重试
                    return true;
                }
                if (exception instanceof SSLHandshakeException) {
                    // 不要重试SSL握手异常
                    return false;
                }
                HttpRequest request = (HttpRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
                boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
                if (idempotent) {
                    // 如果请求被认为是幂等的,那么就重试
                    return true;
                }
                return false;
            }
        })).build();
    } catch (KeyManagementException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (KeyStoreException e) {
        e.printStackTrace();
    }
    return  HttpClients.createDefault();
}

参考:轻松把玩HttpClient之配置ssl,采用绕过证书验证实现https

加载证书来访问HTTPS网站

DefaultHttpClient

1
2
3
4
5
6
7
8
9
10
11
DefaultHttpClient hc = new DefaultHttpClient();
//加载证书  
java.security.KeyStore trustStore = java.security.KeyStore.getInstance(java.security.KeyStore.getDefaultType());  
//"123456"为制作证书时的密码  
trustStore.load(new FileInputStream(new File("你的证书位置")), "123456".toCharArray());  
org.apache.http.conn.ssl.SSLSocketFactory socketFactory = new org.apache.http.conn.ssl.SSLSocketFactory(trustStore);  
//不校验域名  
socketFactory.setHostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);  
//这个8446是和被访问端约定的端口,一般为443  
org.apache.http.conn.scheme.Scheme sch = new org.apache.http.conn.scheme.Scheme("https", socketFactory, 8446);  
hc.getConnectionManager().getSchemeRegistry().register(sch);

参考:http://blog.csdn.net/wangshfa/article/details/9059089

CloseableHttpClient

1
2
3
4
5
6
7
8
9
10
11
12
13
14
KeyStore trustStore  = KeyStore.getInstance(KeyStore.getDefaultType());  
//加载证书文件  
FileInputStream instream = new FileInputStream(new File("/home/victor/my.store"));  
try {  
   trustStore.load(instream, "mypassword".toCharArray());  
} finally {  
   instream.close();  
}  
SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(trustStore).build();  
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext,  
       SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);  
CloseableHttpClient httpclient = HttpClients.custom()  
       .setSSLSocketFactory(sslsf)  
       .build();

参考:http://blog.csdn.net/wanglha/article/details/51140846