關於JAVA發送Https請求(HttpsURLConnection和HttpURLConnection)

【轉】java

https協議對於開發者而言其實只是多了一步證書驗證的過程。這個證書正常狀況下被jdk/jre/security/cacerts所管理。裏面證書包含兩種狀況:json

一、機構所頒發的被認證的證書,這種證書的網站在瀏覽器訪問時https頭顯示爲綠色如百度瀏覽器

 

二、我的所設定的證書,這種證書的網站在瀏覽器裏https頭顯示爲紅色×,且須要點擊信任該網站才能繼續訪問。而點擊信任這一步的操做就是咱們在java代碼訪問https網站時區別於http請求須要作的事情。session

 

 

因此JAVA發送Https請求有兩種狀況,三種解決辦法:app

第一種狀況:Https網站的證書爲機構所頒發的被認證的證書,這種狀況下和http請求如出一轍,無需作任何改變,用HttpsURLConnection或者HttpURLConnection均可以dom

 

  • [java] view plain copy

     

    1. public static void main(String[] args) throws Exception{  
    2.         URL serverUrl = new URL("https://xxxx");  
    3.         HttpURLConnection conn = (HttpURLConnection) serverUrl.openConnection();  
    4.         conn.setRequestMethod("GET");  
    5.         conn.setRequestProperty("Content-type", "application/json");  
    6.         //必須設置false,不然會自動redirect到重定向後的地址  
    7.         conn.setInstanceFollowRedirects(false);  
    8.         conn.connect();  
    9.         String result = getReturn(conn);  
    10.     }  
    11.   
    12.     /*請求url獲取返回的內容*/  
    13.     public static String getReturn(HttpURLConnection connection) throws IOException{  
    14.         StringBuffer buffer = new StringBuffer();  
    15.         //將返回的輸入流轉換成字符串  
    16.         try(InputStream inputStream = connection.getInputStream();  
    17.             InputStreamReader inputStreamReader = new InputStreamReader(inputStream, ConstantInfo.CHARSET);  
    18.             BufferedReader bufferedReader = new BufferedReader(inputStreamReader);){  
    19.             String str = null;  
    20.             while ((str = bufferedReader.readLine()) != null) {  
    21.                 buffer.append(str);  
    22.             }  
    23.             String result = buffer.toString();  
    24.             return result;  
    25.         }  
    26. }  

 

第二種狀況:我的所設定的證書,這種證書默認不被信任,須要咱們本身選擇信任,信任的辦法有兩種:ide

A、將證書導入java的運行環境中網站

 

  • 從該網站下載或者從網站開發者出獲取證書cacert.crt
  • 運行命令將證書導入java運行環境:keytool -import -keystore %JAVA_HOME%\jre\lib\security\cacerts -file cacert.crt -alias xxx
  • 完成。java代碼中發送https的請求和http同樣,同第一種狀況。

B、忽略證書驗證過程,忽略以後任何Https協議網站皆能正常訪問,同第一種狀況this

 

  • [java] view plain copy

     

    1. import java.security.cert.CertificateException;  
    2. import java.security.cert.X509Certificate;  
    3. import javax.net.ssl.X509TrustManager;  
    4. public class MyX509TrustManager implements X509TrustManager {  
    5.   
    6.     @Override  
    7.     public void checkClientTrusted(X509Certificate certificates[],String authType) throws CertificateException {  
    8.     }  
    9.   
    10.     @Override  
    11.     public void checkServerTrusted(X509Certificate[] ax509certificate,String s) throws CertificateException {  
    12.     }  
    13.   
    14.     @Override  
    15.     public X509Certificate[] getAcceptedIssuers() {  
    16.         // TODO Auto-generated method stub  
    17.         return null;  
    18.     }  
    19. }  
  • [java] view plain copy

     

    1. public static void main(String[] args) throws Exception{  
    2.         SSLContext sslcontext = SSLContext.getInstance("SSL","SunJSSE");  
    3.         sslcontext.init(null, new TrustManager[]{new MyX509TrustManager()}, new java.security.SecureRandom());  
    4.         URL url = new URL("https://xxxx");  
    5.         HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() {  
    6.             public boolean verify(String s, SSLSession sslsession) {  
    7.                 System.out.println("WARNING: Hostname is not matched for cert.");  
    8.                 return true;  
    9.             }  
    10.         };  
    11.         HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier);  
    12.         HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());  
    13.         //以後任何Https協議網站皆能正常訪問,同第一種狀況  
    14. }  

 

C、java代碼中加載證書,必須使用HttpsURLConnection方式url

 

 

  • 從網站開發者出獲取生成證書的密鑰庫cacert.keystore
  • [java] view plain copy

     

    1. import java.io.FileInputStream;  
    2. import java.security.KeyStore;  
    3. import java.security.cert.CertificateException;  
    4. import java.security.cert.X509Certificate;  
    5. import javax.net.ssl.TrustManager;  
    6. import javax.net.ssl.TrustManagerFactory;  
    7. import javax.net.ssl.X509TrustManager;  
    8. public class MyX509TrustManager implements X509TrustManager {  
    9.     /* 
    10.      * The default X509TrustManager returned by SunX509.  We'll delegate 
    11.      * decisions to it, and fall back to the logic in this class if the 
    12.      * default X509TrustManager doesn't trust it. 
    13.      */  
    14.     X509TrustManager sunJSSEX509TrustManager;  
    15.     MyX509TrustManager() throws Exception {  
    16.         // create a "default" JSSE X509TrustManager.  
    17.         KeyStore ks = KeyStore.getInstance("JKS");  
    18.         ks.load(new FileInputStream("cancert.keystore"),  
    19.                 "changeit".toCharArray());  
    20.         TrustManagerFactory tmf =  
    21.                 TrustManagerFactory.getInstance("SunX509", "SunJSSE");  
    22.         tmf.init(ks);  
    23.         TrustManager tms [] = tmf.getTrustManagers();  
    24.             /* 
    25.              * Iterate over the returned trustmanagers, look 
    26.              * for an instance of X509TrustManager.  If found, 
    27.              * use that as our "default" trust manager. 
    28.              */  
    29.         for (int i = 0; i < tms.length; i++) {  
    30.             if (tms[i] instanceof X509TrustManager) {  
    31.                 sunJSSEX509TrustManager = (X509TrustManager) tms[i];  
    32.                 return;  
    33.             }  
    34.         }  
    35.             /* 
    36.              * Find some other way to initialize, or else we have to fail the 
    37.              * constructor. 
    38.              */  
    39.         throw new Exception("Couldn't initialize");  
    40.     }  
    41.     /* 
    42.      * Delegate to the default trust manager. 
    43.      */  
    44.     public void checkClientTrusted(X509Certificate[] chain, String authType)  
    45.             throws CertificateException {  
    46.         try {  
    47.             sunJSSEX509TrustManager.checkClientTrusted(chain, authType);  
    48.         } catch (CertificateException excep) {  
    49.             // do any special handling here, or rethrow exception.  
    50.         }  
    51.     }  
    52.     /* 
    53.      * Delegate to the default trust manager. 
    54.      */  
    55.     public void checkServerTrusted(X509Certificate[] chain, String authType)  
    56.             throws CertificateException {  
    57.         try {  
    58.             sunJSSEX509TrustManager.checkServerTrusted(chain, authType);  
    59.         } catch (CertificateException excep) {  
    60.                 /* 
    61.                  * Possibly pop up a dialog box asking whether to trust the 
    62.                  * cert chain. 
    63.                  */  
    64.         }  
    65.     }  
    66.     /* 
    67.      * Merely pass this through. 
    68.      */  
    69.     public X509Certificate[] getAcceptedIssuers() {  
    70.         return sunJSSEX509TrustManager.getAcceptedIssuers();  
    71.     }  
    72. }  
  • [java] view plain copy

     

    1.   
    [java] view plain copy

     

    1. public static void main(String[] args) throws Exception{  
    2.         SSLContext sslcontext = SSLContext.getInstance("SSL","SunJSSE");  
    3.         sslcontext.init(null, new TrustManager[]{new MyX509TrustManager()}, new java.security.SecureRandom());  
    4.         URL serverUrl = new URL("https://xxxx");  
    5.         HttpsURLConnection conn = (HttpsURLConnection) serverUrl.openConnection();  
    6.         conn.setSSLSocketFactory(sslcontext.getSocketFactory());  
    7.         conn.setRequestMethod("GET");  
    8.         conn.setRequestProperty("Content-type", "application/json");  
    9.         //必須設置false,不然會自動redirect到重定向後的地址  
    10.         conn.setInstanceFollowRedirects(false);  
    11.         conn.connect();  
    12.         String result = getReturn(conn);  
    13.     }  
    14.   
    15.     /*請求url獲取返回的內容*/  
    16.     public static String getReturn(HttpsURLConnection connection) throws IOException{  
    17.         StringBuffer buffer = new StringBuffer();  
    18.         //將返回的輸入流轉換成字符串  
    19.         try(InputStream inputStream = connection.getInputStream();  
    20.             InputStreamReader inputStreamReader = new InputStreamReader(inputStream, ConstantInfo.CHARSET);  
    21.             BufferedReader bufferedReader = new BufferedReader(inputStreamReader);){  
    22.             String str = null;  
    23.             while ((str = bufferedReader.readLine()) != null) {  
    24.                 buffer.append(str);  
    25.             }  
    26.             String result = buffer.toString();  
    27.             return result;  
    28.         }  
    29. }  
相關文章
相關標籤/搜索