关于JAVA发送Https请求(HttpsURLConnection和
HttpURLCon。。。
关于JAVA发送Https请求(HttpsURLConnection和HttpURLConnection)
【转】
https协议对于开发者⽽⾔其实只是多了⼀步证书验证的过程。这个证书正常情况下被jdk/jre/security/cacerts所管理。⾥⾯证书包含两种情况:
1、机构所颁发的被认证的证书,这种证书的⽹站在浏览器访问时https头显⽰为绿⾊如百度
2、个⼈所设定的证书,这种证书的⽹站在浏览器⾥https头显⽰为红⾊×,且需要点击信任该⽹站才能继续访问。⽽点击信任这⼀步的操作就是我们在java代码访问https⽹站时区别于http请求需要做的事情。
所以JAVA发送Https请求有两种情况,三种解决办法:
第⼀种情况:Https⽹站的证书为机构所颁发的被认证的证书,这种情况下和http请求⼀模⼀样,⽆需做任何改变,⽤HttpsURLConnection或者HttpURLConnection都可以
[java]
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\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]
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]
1. public static void main(String[] args) throws Exception{
2. SSLContext sslcontext = SSLContext.getInstance(\"SSL\
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]
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\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. */ . } 65. } 66. /*
67. * Merely pass this through. 68. */
69. public X509Certificate[] getAcceptedIssuers() {
70. return sunJSSEX509TrustManager.getAcceptedIssuers(); 71. } 72. } [java]
1. [java]
1. public static void main(String[] args) throws Exception{
2. SSLContext sslcontext = SSLContext.getInstance(\"SSL\
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\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. } 30.