如何使用HttpsUrlConnection而不是DefaultHttpClient

时间:2015-12-15 15:59:20

标签: android httpsurlconnection

不推荐使用DefaultHttpClient,ThreadSafeClientConnManager,HttpParams,HttpProtocolParams,SchemeRegistry,SSLSocketFactory,NameValuePair,HttpResponse。

我尝试使用HttpsUrlConnection,但我对它们感到困惑。

protected Gson gson;
private ThreadSafeClientConnManager threadSafeClientConnManager;
private DefaultHttpClient client;

AbstractServiceApi() {

    // sets up parameters
    HttpParams params = new BasicHttpParams();
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(params, ENCODING);
    HttpConnectionParams.setConnectionTimeout(params, 95 * 1000);
    HttpConnectionParams.setSoTimeout(params, 95 * 1000);
    HttpConnectionParams.setStaleCheckingEnabled(params, false);
    params.setBooleanParameter("http.protocol.expect-continue", false);

    // registers schemes for both http and https
    SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    SSLSocketFactory sslSocketFactory = SSLSocketFactory.getSocketFactory();
    sslSocketFactory.setHostnameVerifier(SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
    registry.register(new Scheme("https", sslSocketFactory, 443));

    threadSafeClientConnManager = new ThreadSafeClientConnManager(params, registry);
    client = new DefaultHttpClient(threadSafeClientConnManager, params);
    gson = new Gson();
}

我没有密钥库。 https://developer.android.com/reference/javax/net/ssl/HttpsURLConnection.html

   KeyStore keyStore = ...;
   String algorithm = TrustManagerFactory.getDefaultAlgorithm();
   TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
   tmf.init(keyStore);

   SSLContext context = SSLContext.getInstance("TLS");
   context.init(null, tmf.getTrustManagers(), null);

   URL url = new URL("https://www.example.com/");
   HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
   urlConnection.setSSLSocketFactory(context.getSocketFactory());
   InputStream in = urlConnection.getInputStream();

任何人都可以帮助我吗?

4 个答案:

答案 0 :(得分:7)

这是我的解决方案。

private HttpsURLConnection urlConnection;
private CookieManager cookieManager;

private HttpsURLConnection getConnection(String url) throws MalformedURLException {
    URL request_url = new URL(url);
    try {
        if (!isHttps()) {
            throw new ConnectException("you have to use SSL certifacated url!");
        }
        urlConnection = (HttpsURLConnection) request_url.openConnection();
        urlConnection.setRequestMethod("POST");
        urlConnection.setReadTimeout(95 * 1000);
        urlConnection.setConnectTimeout(95 * 1000);
        urlConnection.setDoInput(true);
        urlConnection.setRequestProperty("Accept", "application/json");
        urlConnection.setRequestProperty("X-Environment", "android");

        /** Cookie Sets... */
        String cookie = cookieManager.getCookie(urlConnection.getURL().toString());
        cookieManager = CookieManager.getInstance();
        if (cookie != null)
            urlConnection.setRequestProperty("Cookie", cookie);

        List<String> cookieList = urlConnection.getHeaderFields().get("Set-Cookie");
        if (cookieList != null) {
            for (String cookieTemp : cookieList) {
                cookieManager.setCookie(urlConnection.getURL().toString(), cookieTemp);
            }
        }
        /** Cookie Sets... */

        urlConnection.setHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                /** if it necessarry get url verfication */
                //return HttpsURLConnection.getDefaultHostnameVerifier().verify("your_domain.com", session);
                return true;
            }
        });
        urlConnection.setSSLSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault());


        urlConnection.connect();

    } catch (IOException e) {
        e.printStackTrace();
    }

    return urlConnection;
}

答案 1 :(得分:5)

对于HttpsUrlConnection,您可以参考我的以下示例代码:

    private TrustManager[] getWrappedTrustManagers(TrustManager[] trustManagers) {
        final X509TrustManager originalTrustManager = (X509TrustManager) trustManagers[0];
        return new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return originalTrustManager.getAcceptedIssuers();
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                        try {
                            originalTrustManager.checkClientTrusted(certs, authType);
                        } catch (CertificateException ignored) {
                        }
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                        try {
                            originalTrustManager.checkServerTrusted(certs, authType);
                        } catch (CertificateException ignored) {
                        }
                    }
                }
        };
    }

    private SSLSocketFactory getSSLSocketFactory() {
        try {
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            InputStream caInput = getResources().openRawResource(R.raw.your_cert);
            Certificate ca = cf.generateCertificate(caInput);
            caInput.close();

            KeyStore keyStore = KeyStore.getInstance("BKS");
            keyStore.load(null, null);
            keyStore.setCertificateEntry("ca", ca);

            String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
            TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
            tmf.init(keyStore);

            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, getWrappedTrustManagers(tmf.getTrustManagers()), null);                

            return sslContext.getSocketFactory();
        } catch (Exception e) {
            return HttpsURLConnection.getDefaultSSLSocketFactory();
        }
    }

    private class GETRequest extends AsyncTask<Void, Void, String> {
        @Override
        protected String doInBackground(Void... params) {
            try {
                URL url = new URL("https://your_server_url");
                String token = "rbkY34HnL...";
                HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
                urlConnection.setSSLSocketFactory(getSSLSocketFactory());
                urlConnection.setHostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
//                        return true;
                        HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
                        return hv.verify("your_domain.com", session);
                    }
                });    
                urlConnection.setRequestProperty("Authorization", "Bearer " + token);
                urlConnection.connect();
                InputStream inputStream;
                if (urlConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                    inputStream = urlConnection.getErrorStream();
                } else {
                    inputStream = urlConnection.getInputStream();
                }
                return String.valueOf(urlConnection.getResponseCode()) + " " + urlConnection.getResponseMessage() + "\r\n" + parseStream(inputStream);
            } catch (Exception e) {
                return e.toString();
            }
        }

        @Override
        protected void onPostExecute(String response) {
            super.onPostExecute(response);
            // do something...
        }
    }

希望它有所帮助!

答案 2 :(得分:4)

您可以使用HttpURLConnection进行https通信 (http://developer.android.com/reference/java/net/HttpURLConnection.html

据我了解,您使用知名证书与Web服务器进行通信。在这种情况下,它看起来像:

    public static final int CONNECTON_TIMEOUT_MILLISECONDS = 60000;

public static String executeGetHttpRequest(final String path) throws ClientProtocolException, IOException {
    String result = null;
    HttpURLConnection urlConnection = null;
    try {
        URL url = new URL(path);
        urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setConnectTimeout(CONNECTON_TIMEOUT_MILLISECONDS);
        urlConnection.setReadTimeout(CONNECTON_TIMEOUT_MILLISECONDS);
        result = readStream(urlConnection.getInputStream());
    } finally {
        if (urlConnection != null) {
            urlConnection.disconnect();
        }
    }
    return result;
}

private static String readStream(InputStream is) throws IOException {
    final BufferedReader reader = new BufferedReader(new InputStreamReader(is, Charset.forName("US-ASCII")));
    StringBuilder total = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null) {
        total.append(line);
    }
    if (reader != null) {
        reader.close();
    }
    return total.toString();
}

它的工作样本。您可以查看这篇描述不同案例的好文章 - http://developer.android.com/training/articles/security-ssl.html

答案 3 :(得分:0)

您可以通过这种方式使用HttpURLConnection

#import <AVFoundation/AVFoundation.h>