【问题标题】:how to use HttpsUrlConnection instead of DefaultHttpClient如何使用 HttpsUrlConnection 而不是 DefaultHttpClient
【发布时间】:2015-12-15 15:59:19
【问题描述】:

不推荐使用 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();

谁能帮帮我?

【问题讨论】:

    标签: android httpsurlconnection


    【解决方案1】:

    这是我的解决方案。

    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;
    }
    

    【讨论】:

    • 为什么只返回true?这是否意味着您没有确认该域已通过验证?
    • 这只是一个示例。如果您需要在被评论的行之前使用。
    【解决方案2】:

    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...
            }
        }
    

    希望对你有帮助!

    【讨论】:

    【解决方案3】:

    您可以使用 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

    【讨论】:

      【解决方案4】:

      这样就可以使用HttpURLConnection了

      URL url = new URL(urlString);
      
          HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
          urlConnection.setRequestMethod("GET");
          urlConnection.connect();
      
          // Read the input stream into a String
          InputStream inputStream = urlConnection.getInputStream();
          StringBuffer buffer = new StringBuffer();
          if (inputStream == null) {
              // Nothing to do.
              return null;
          }
      
          BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
          String line;
          while ((line = reader.readLine()) != null) {
              buffer.append(line + "\n");
          }
      
          if (buffer.length() == 0) {
              return null;
          }
      
          String stringResult = buffer.toString();
      

      【讨论】:

      • 我需要 Https 协议。 HttpUrlConnection 没问题。
      • 问题是关于 https 连接的。
      猜你喜欢
      • 2014-11-04
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      • 2019-10-19
      • 2016-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多