Java中发起http和https请求
一般调用外部接口会需要用到http和https请求。
本案例为:前后端完全分离,前端框架(React+Mobx+Nornj),后端(Go语言)。
面临问题:跨域问题。(线上允许跨域访问)
解决方案:java发起https请求代理。(起到数据中转作用)
一。发起http请求
参考博客:https://blog.csdn.net/guozili1/article/details/53995121
1。写http请求方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //处理http请求 requestUrl为请求地址 requestMethod请求方式,值为"GET"或"POST" 2 public static String httpRequest(String requestUrl,String requestMethod,String outputStr){ 3 StringBuffer buffer=null; 4 try{ 5 URL url=new URL(requestUrl); 6 HttpURLConnection conn=(HttpURLConnection)url.openConnection(); 7 conn.setDoOutput(true); 8 conn.setDoInput(true); 9 conn.setRequestMethod(requestMethod); 10 conn.connect(); 11 //往服务器端写内容 也就是发起http请求需要带的参数 12 if(null!=outputStr){ 13 OutputStream os=conn.getOutputStream(); 14 os.write(outputStr.getBytes("utf-8")); 15 os.close(); 16 } 17 18 //读取服务器端返回的内容 19 InputStream is=conn.getInputStream(); 20 InputStreamReader isr=new InputStreamReader(is,"utf-8"); 21 BufferedReader br=new BufferedReader(isr); 22 buffer=new StringBuffer(); 23 String line=null; 24 while((line=br.readLine())!=null){ 25 buffer.append(line); 26 } 27 }catch(Exception e){ 28 e.printStackTrace(); 29 } 30 return buffer.toString(); 31 }
2。测试
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public static void main(String[] args){ 2 String s=httpRequest("http://www.qq.com","GET",null); 3 System.out.println(s); 4 }
注意:
1).第一个参数url需要写全地址,即前边的http必须写上,不能只写www.qq.com这样的。
2).第二个参数是请求方式,一般接口调用会给出URL和请求方式说明。
3).第三个参数是我们在发起请求的时候传递参数到所要请求的服务器,要传递的参数也要看接口文档确定格式,一般是封装成json或xml.
4).返回内容是String类,但是一般是有格式的json或者xml。
二。发起https请求
https是对链接加了安全证书SSL的,如果服务器中没有相关链接的SSL证书,它就不能够信任那个链接,也就不会访问到了。所以我们第一步是自定义一个信任管理器。自要实现自带的X509TrustManager接口就可以了。
1。自定义证书信任管理器
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 import java.security.cert.CertificateException; 2 import java.security.cert.X509Certificate; 3 import javax.net.ssl.X509TrustManager; 4 5 public class MyX509TrustManager implements X509TrustManager { 6 7 @Override 8 public void checkClientTrusted(X509Certificate[] chain, String authType) 9 throws CertificateException { 10 // TODO Auto-generated method stub 11 12 } 13 14 @Override 15 public void checkServerTrusted(X509Certificate[] chain, String authType) 16 throws CertificateException { 17 // TODO Auto-generated method stub 18 19 } 20 21 @Override 22 public X509Certificate[] getAcceptedIssuers() { 23 // TODO Auto-generated method stub 24 return null; 25 } 26 27 }
注意:
1)需要的包都是java自带的,所以不用引入额外的包。
2.)可以看到里面的方法都是空的,当方法为空是默认为所有的链接都为安全,也就是所有的链接都能够访问到。当然这样有一定的安全风险,可以根据实际需要写入内容。
2。编写http请求方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 * 处理https GET/POST请求 3 * 请求地址、请求方法、参数 4 * */ 5 public static String httpsRequest(String requestUrl,String requestMethod,String outputStr){ 6 StringBuffer buffer=null; 7 try{ 8 //创建SSLContext 9 SSLContext sslContext=SSLContext.getInstance("SSL"); 10 TrustManager[] tm={new MyX509TrustManager()}; 11 //初始化 12 sslContext.init(null, tm, new java.security.SecureRandom());; 13 //获取SSLSocketFactory对象 14 SSLSocketFactory ssf=sslContext.getSocketFactory(); 15 URL url=new URL(requestUrl); 16 HttpsURLConnection conn=(HttpsURLConnection)url.openConnection(); 17 conn.setDoOutput(true); 18 conn.setDoInput(true); 19 conn.setUseCaches(false); 20 conn.setRequestMethod(requestMethod); 21 //设置当前实例使用的SSLSoctetFactory 22 conn.setSSLSocketFactory(ssf); 23 conn.connect(); 24 //往服务器端写内容 25 if(null!=outputStr){ 26 OutputStream os=conn.getOutputStream(); 27 os.write(outputStr.getBytes("utf-8")); 28 os.close(); 29 } 30 31 //读取服务器端返回的内容 32 InputStream is=conn.getInputStream(); 33 InputStreamReader isr=new InputStreamReader(is,"utf-8"); 34 BufferedReader br=new BufferedReader(isr); 35 buffer=new StringBuffer(); 36 String line=null; 37 while((line=br.readLine())!=null){ 38 buffer.append(line); 39 } 40 }catch(Exception e){ 41 e.printStackTrace(); 42 } 43 return buffer.toString(); 44 }
可见和http访问的方法类似,只是多了SSL的相关处理。
3。测试
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public static void main(String[] args){ 2 String s=httpsRequest("https://kyfw.12306.cn/","GET",null); 3 System.out.println(s); 4 }
https的链接一定要进行SSL的验证或者过滤之后才能够访问。
项目应用:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.jd.ofc.trace.web.controller; 2 3 import javax.net.ssl.*; 4 import java.io.BufferedReader; 5 import java.io.InputStream; 6 import java.io.InputStreamReader; 7 import java.io.OutputStream; 8 import java.net.URL; 9 import java.security.cert.CertificateException; 10 import java.security.cert.X509Certificate; 11 /** 12 * 证书信任管理器(用于https请求) 13 * */ 14 public class MyX509TrustManager1 implements X509TrustManager { 15 @Override 16 public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { 17 18 } 19 20 @Override 21 public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { 22 23 } 24 25 @Override 26 public X509Certificate[] getAcceptedIssuers() { 27 return new X509Certificate[0]; 28 } 29 30 31 /* 32 * 处理https GET/POST请求 33 * 请求地址、请求方法、参数 34 * */ 35 public static String httpsRequest(String requestUrl, String requestMethod, String outputStr){ 36 StringBuffer buffer=null; 37 try{ 38 //创建SSLContext 39 SSLContext sslContext=SSLContext.getInstance("SSL"); 40 TrustManager[] tm={new MyX509TrustManager1()}; 41 //初始化 42 sslContext.init(null, tm, new java.security.SecureRandom());; 43 //获取SSLSocketFactory对象 44 SSLSocketFactory ssf=sslContext.getSocketFactory(); 45 URL url=new URL(requestUrl); 46 HttpsURLConnection conn=(HttpsURLConnection)url.openConnection(); 47 48 String cookies="__jdv=XXX"; 49 50 conn.setRequestProperty("Authorization","Basic XXX"); 51 conn.setRequestProperty("cookie",cookies); 52 conn.setDoOutput(true); 53 conn.setDoInput(true); 54 conn.setUseCaches(false); 55 conn.setRequestMethod(requestMethod); 56 //设置当前实例使用的SSLSoctetFactory 57 conn.setSSLSocketFactory(ssf); 58 59 conn.connect(); 60 //往服务器端写内容 61 if(null!=outputStr){ 62 OutputStream os=conn.getOutputStream(); 63 os.write(outputStr.getBytes("utf-8")); 64 os.close(); 65 } 66 67 //读取服务器端返回的内容 68 InputStream is=conn.getInputStream(); 69 InputStreamReader isr=new InputStreamReader(is,"utf-8"); 70 BufferedReader br=new BufferedReader(isr); 71 buffer=new StringBuffer(); 72 String line=null; 73 while((line=br.readLine())!=null){ 74 buffer.append(line); 75 } 76 }catch(Exception e){ 77 e.printStackTrace(); 78 } 79 return buffer.toString(); 80 } 81 82 public static void main(String[] args){ 83 String s=httpsRequest("https://xx.xx.com/v3/clusters?limit=-1&sort=name","GET",null); 84 System.out.println(s); 85 } 86 }