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

it2022-05-09  38

关于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   public static void main(String[] args) throws Exception{          URL serverUrl = new URL("https://xxxx");          HttpURLConnection conn = (HttpURLConnection) serverUrl.openConnection();          conn.setRequestMethod("GET");          conn.setRequestProperty("Content-type", "application/json");          //必须设置false,否则会自动redirect到重定向后的地址          conn.setInstanceFollowRedirects(false);          conn.connect();          String result = getReturn(conn);      }        /*请求url获取返回的内容*/      public static String getReturn(HttpURLConnection connection) throws IOException{          StringBuffer buffer = new StringBuffer();          //将返回的输入流转换成字符串          try(InputStream inputStream = connection.getInputStream();              InputStreamReader inputStreamReader = new InputStreamReader(inputStream, ConstantInfo.CHARSET);              BufferedReader bufferedReader = new BufferedReader(inputStreamReader);){              String str = null;              while ((str = bufferedReader.readLine()) != null) {                  buffer.append(str);              }              String result = buffer.toString();              return result;          }  }  

 

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

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   import java.security.cert.CertificateException;  import java.security.cert.X509Certificate;  import javax.net.ssl.X509TrustManager;  public class MyX509TrustManager implements X509TrustManager {        @Override      public void checkClientTrusted(X509Certificate certificates[],String authType) throws CertificateException {      }        @Override      public void checkServerTrusted(X509Certificate[] ax509certificate,String s) throws CertificateException {      }        @Override      public X509Certificate[] getAcceptedIssuers() {          // TODO Auto-generated method stub          return null;      }  }   [java]  view plain  copy   public static void main(String[] args) throws Exception{          SSLContext sslcontext = SSLContext.getInstance("SSL","SunJSSE");          sslcontext.init(null, new TrustManager[]{new MyX509TrustManager()}, new java.security.SecureRandom());          URL url = new URL("https://xxxx");          HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() {              public boolean verify(String s, SSLSession sslsession) {                  System.out.println("WARNING: Hostname is not matched for cert.");                  return true;              }          };          HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier);          HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());          //之后任何Https协议网站皆能正常访问,同第一种情况  }  

 

C、java代码中加载证书,必须使用HttpsURLConnection方式

 

 

从网站开发者出获取生成证书的密钥库cacert.keystore [java]  view plain  copy   import java.io.FileInputStream;  import java.security.KeyStore;  import java.security.cert.CertificateException;  import java.security.cert.X509Certificate;  import javax.net.ssl.TrustManager;  import javax.net.ssl.TrustManagerFactory;  import javax.net.ssl.X509TrustManager;  public class MyX509TrustManager implements X509TrustManager {      /*      * The default X509TrustManager returned by SunX509.  We'll delegate      * decisions to it, and fall back to the logic in this class if the      * default X509TrustManager doesn't trust it.      */      X509TrustManager sunJSSEX509TrustManager;      MyX509TrustManager() throws Exception {          // create a "default" JSSE X509TrustManager.          KeyStore ks = KeyStore.getInstance("JKS");          ks.load(new FileInputStream("cancert.keystore"),                  "changeit".toCharArray());          TrustManagerFactory tmf =                  TrustManagerFactory.getInstance("SunX509", "SunJSSE");          tmf.init(ks);          TrustManager tms [] = tmf.getTrustManagers();              /*              * Iterate over the returned trustmanagers, look              * for an instance of X509TrustManager.  If found,              * use that as our "default" trust manager.              */          for (int i = 0; i < tms.length; i++) {              if (tms[i] instanceof X509TrustManager) {                  sunJSSEX509TrustManager = (X509TrustManager) tms[i];                  return;              }          }              /*              * Find some other way to initialize, or else we have to fail the              * constructor.              */          throw new Exception("Couldn't initialize");      }      /*      * Delegate to the default trust manager.      */      public void checkClientTrusted(X509Certificate[] chain, String authType)              throws CertificateException {          try {              sunJSSEX509TrustManager.checkClientTrusted(chain, authType);          } catch (CertificateException excep) {              // do any special handling here, or rethrow exception.          }      }      /*      * Delegate to the default trust manager.      */      public void checkServerTrusted(X509Certificate[] chain, String authType)              throws CertificateException {          try {              sunJSSEX509TrustManager.checkServerTrusted(chain, authType);          } catch (CertificateException excep) {                  /*                  * Possibly pop up a dialog box asking whether to trust the                  * cert chain.                  */          }      }      /*      * Merely pass this through.      */      public X509Certificate[] getAcceptedIssuers() {          return sunJSSEX509TrustManager.getAcceptedIssuers();      }  }   [java]  view plain  copy      [java]  view plain  copy   public static void main(String[] args) throws Exception{          SSLContext sslcontext = SSLContext.getInstance("SSL","SunJSSE");          sslcontext.init(null, new TrustManager[]{new MyX509TrustManager()}, new java.security.SecureRandom());          URL serverUrl = new URL("https://xxxx");          HttpsURLConnection conn = (HttpsURLConnection) serverUrl.openConnection();          conn.setSSLSocketFactory(sslcontext.getSocketFactory());          conn.setRequestMethod("GET");          conn.setRequestProperty("Content-type", "application/json");          //必须设置false,否则会自动redirect到重定向后的地址          conn.setInstanceFollowRedirects(false);          conn.connect();          String result = getReturn(conn);      }        /*请求url获取返回的内容*/      public static String getReturn(HttpsURLConnection connection) throws IOException{          StringBuffer buffer = new StringBuffer();          //将返回的输入流转换成字符串          try(InputStream inputStream = connection.getInputStream();              InputStreamReader inputStreamReader = new InputStreamReader(inputStream, ConstantInfo.CHARSET);              BufferedReader bufferedReader = new BufferedReader(inputStreamReader);){              String str = null;              while ((str = bufferedReader.readLine()) != null) {                  buffer.append(str);              }              String result = buffer.toString();              return result;          }  }  

 

转载于:https://www.cnblogs.com/mengen/p/9138214.html


最新回复(0)