2015-12-15 17 views
3

不推薦使用DefaultHttpClient,ThreadSafeClientConnManager,HttpProtocolParams,SchemeRegistry,SSLSocketFactory,NameValuePair,HttpResponse。如何使用HttpsUrlConnection而不是DefaultHttpClient

我試過使用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(); 

任何人都可以幫助我嗎?

回答

6

這是我的解決方案。

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

爲什麼只返回true?這是不是意味着你沒有確認該域名已被驗證? – portfoliobuilder

+0

這只是一個樣本。如果你需要在被評論的行之前使用。 – Kaloglu

+1

工作很好Kaloglu,無論如何謝謝你...... – yasriady

0

您可以通過這種方式使用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(); 
+0

我需要Https協議。 HttpUrlConnection沒問題。 – Kaloglu

+0

問題是關於https連接。 –

4

你可以使用HttpURLConnection的 (http://developer.android.com/reference/java/net/HttpURLConnection.html

據我瞭解你的Web服務器進行通信與衆所周知的證書使用HTTPS通信。在這種情況下,它看起來像:

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

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

希望它能幫助!

+0

如果你想忽略SSL的開發,你也可以閱讀我的答案在http://stackoverflow.com/questions/32051482/how-can-i-set-signalr-in-android-studio-to-ignore-ssl -issues-for-delvelopement/32051885#32051885 – BNK

相關問題