zoukankan      html  css  js  c++  java
  • 关于JAVA发送Https请求(HttpsURLConnection和HttpURLConnection)

    关于JAVA发送Https请求(HttpsURLConnection和HttpURLConnection)

    https协议对于开发者而言其实只是多了一步证书验证的过程。这个证书正常情况下被jdk/jre/security/cacerts所管理。里面证书包含两种情况:

    1、机构所颁发的被认证的证书,这种证书的网站在浏览器访问时https头显示为绿色如百度

    2、个人所设定的证书,这种证书的网站在浏览器里https头显示为红色×,且需要点击信任该网站才能继续访问。而点击信任这一步的操作就是我们在java代码访问https网站时区别于http请求需要做的事情。

    所以JAVA发送Https请求有两种情况,三种解决办法:

    第一种情况:Https网站的证书为机构所颁发的被认证的证书,这种情况下和http请求一模一样,无需做任何改变,用HttpsURLConnection或者HttpURLConnection都可以

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

    第二种情况:个人所设定的证书,这种证书默认不被信任,需要我们自己选择信任,信任的办法有两种:

    A、将证书导入java的运行环境中

    • 从该网站下载或者从网站开发者出获取证书cacert.crt
    • 运行命令将证书导入java运行环境:keytool -import -keystore %JAVA_HOME%\jre\lib\security\cacerts -file cacert.crt -alias xxx
    • 完成。java代码中发送https的请求和http一样,同第一种情况。

    B、忽略证书验证过程,忽略之后任何Https协议网站皆能正常访问,同第一种情况

    • [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方式

    • 从网站开发者出获取生成证书的密钥库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. }  
      
      
  • 相关阅读:
    面向对象下
    面向对象上
    将博客搬至CSDN
    矩阵的常用术语和操作
    python2.7 Unable to find vcvarsall.bat
    intellij创建maven web项目
    intellij 编译 springmvc+hibernate+spring+maven 找不到hbm.xml映射文件
    spring Thymeleaf 中文乱码
    visualstudiocode 调试electron
    android反编译工具总结
  • 原文地址:https://www.cnblogs.com/mengen/p/9138214.html
Copyright © 2011-2022 走看看