package com.gblfy.qywx.utils;
import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URL;
 import java.security.KeyManagementException;
 import java.security.NoSuchAlgorithmException;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import java.util.Properties;import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.HttpsURLConnection;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSession;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509TrustManager;import com.alibaba.fastjson.JSONException;
 import org.springframework.stereotype.Component;/**
• 实现HTTPS协议POST请求JSON报文
• 
• 实现流程: 1.在hosts文件中配置域名和ip地址的映射关系 2.在程序中设置代理服务器 3.需要网络处配置发出权限
• 
• 
• @author gblfy
• @date 2020-06-25
 */
 @Component
 public class HttpsApiUtil {
private static class TrustAnyTrustManager implements X509TrustManager {
 // 该方法检查客户端的证书,若不信任该证书则抛出异常。由于我们不需要对客户端进行认证,因此我们只需要执行默认的信任管理器的这个方法。
 // JSSE中,默认的信任管理器类为TrustManager。
 @Override
 public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
 } /*
  * 该方法检查服务器的证书,若不信任该证书同样抛出异常。通过自己实现该方法,可以使之信任我们指定的任何证书。 在实现该方法时,也可以简单的不做任何处理,
  * 即一个空的函数体,由于不会抛出异常,它就会信任任何证书。(non-Javadoc)
  */
 @Override
 public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
 }
 // 返回受信任的X509证书数组。
 @Override
 public X509Certificate[] getAcceptedIssuers() {
  return new X509Certificate[] {};
 }}
private static class TrustAnyHostnameVerifier implements HostnameVerifier {
 @Override
 public boolean verify(String hostname, SSLSession session) {
 return true;
 }
 }/**
• post方式请求服务器(https协议)
• 
• @param url 求地址
• @param content 参数
• @param charset 编码
• @return
• @throws NoSuchAlgorithmException
• @throws KeyManagementException
• @throws IOException
 */
 public static byte[] sendJsonToHttpsPost(String url, String content, String charset)
 throws NoSuchAlgorithmException, KeyManagementException, IOException {
//仅仅本地测试使用
 // 设置服务器代理 每个环境不一样,以具体数据为主
 // Properties prop = System.getProperties();
 // String ress = “192.5.32.xx”;
 // prop.put(“http.proxySet”, “true”);
 // prop.put(“http.proxyHost”, ress);
 // prop.put(“http.proxyPort”, “80”);
 // prop.put(“https.proxyHost”, ress);
 // prop.put(“https.proxyPort”, “80”);
 // prop.put(“http.nonProxyHosts”, “192*|10*”);
/*• 类HttpsURLConnection似乎并没有提供方法设置信任管理器。其实,
• HttpsURLConnection通过SSLSocket来建立与HTTPS的安全连接
• ,SSLSocket对象是由SSLSocketFactory生成的。 HttpsURLConnection提供了方法setSSLSocketFactory
• (SSLSocketFactory)设置它使用的SSLSocketFactory对象。
• SSLSocketFactory通过SSLContext对象来获得,在初始化SSLContext对象时,可指定信任管理器对象。
*/
SSLContext sc = SSLContext.getInstance(“SSL”);
sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());URL console = new URL(url);
 HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
 conn.setSSLSocketFactory(sc.getSocketFactory());
 conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
 conn.setDoOutput(true);
 // 设置请求头
 conn.setRequestProperty(“Content-Type”, “application/json;charset=utf-8”);
 conn.connect();
 // 设置连接超时时间 单位/毫秒 以需求为准
 // conn.setConnectTimeout(30000);
 DataOutputStream out = new DataOutputStream(conn.getOutputStream());
 out.write(content.getBytes(charset));
 // 刷新、关闭
 out.flush();
 out.close();
 InputStream is = conn.getInputStream();
 if (is != null) {
 ByteArrayOutputStream outStream = new ByteArrayOutputStream();
 byte[] buffer = new byte[1024];
 int len = 0;
 while ((len = is.read(buffer)) != -1) {
 outStream.write(buffer, 0, len);
 }
 is.close();
 return outStream.toByteArray();
 }
 return null;
 }// /**
 // * fastjson 处理/解析报文
 // * com.alibaba.fastjson.JSON
 // *
 // * @param args
 // * @throws NoSuchAlgorithmException
 // * @throws KeyManagementException
 // * @throws IOException // * @throws JSONException
 // */
 public static void main(String[] args) throws NoSuchAlgorithmException, KeyManagementException, IOException, JSONException {
 // String url = “https://mi.szpisp.cn/api/szia/yb/refund?access_token=d95379f6874a419891a47c677169896a”;
 // byte[] bytes = sendJsonToHttpsPost(url, “{“name”:“ly”}”, “utf-8”);
 // String url = “https://mi.szpisp.cn/api/szia/YB119?access_token=d95379f6874a419891a47c677169896a”;
 // String postdata = “{“aae011”: “GRUOPSYS”,“ahb516”: “9”,“akb065”: 9817,“bad766”: “20200819”,“cke100”: “ZSXN2020082215980811298”,“cke106”: “XHLC”,“cke107”: “新华人寿保险股份有限公司深圳分公司”}”;   String url = "https://console-mock.apipost.cn/app/mock/project/318ad161-d76d-4ea6-a0e8-87cb97c2d374/apis";
   String postdata = "{\r\n" +
         "\"data\":\"ApYnXBUJeOnPOYpaM8REL7w3IgFceE2kejczj0cJ1yjlS8wdqS+YQu7JlEQyRIDqs\r\n" +
         "0oKjrvtdsidjk/+r0pYFhauEMjzktfxAKUh87SwCMIADR44rxV/iwn3cmJHEHOCMN0AGq7RQn\r\n" +
         "kIEHJEE0whmsaPv+H7usCq6VkhwA/7hic+ISEhvLuoBhBTcR1oio0KVDq/80nTf181CX6S8x2B\r\n" +
         "FrViDSEnKkCX5heWg7jnXlckY9htgzHYs02qM2WkK7/n9JG2qUFVnoVD14eGw0WF2KPbTvE\r\n" +
         "04TKW/y76TvLU/ZMIjdC+hUEIfsaL7uqfZ7O4vO6PWbQigYS0ulqANe+Evn5yil/DhBnr2Zo5z\r\n" +
         "3+XmjilR+XbuPFKpXki/Zo+WFCymxQce3kXzoIGLNd7lWacoHb7jsMHqk0Q+COVmtObRQ\r\n" +
         "8=\",\r\n" +
         "\"r";
   //    JSONObject jsonObject = new JSONObject(postdata);
    byte[] bytes = sendJsonToHttpsPost(url, "", "utf-8");
    // byte[] bytes = sendJsonToHttpsPost(url, postdata, "utf-8");
    System.out.println("服务端返回报文:" + new String(bytes));
    // String url = "https://127.0.0.1:8888/postToJson";
    // byte[] bytes = sendJsonToHttpsPost(url, "{\"name\":\"ly\"}", "utf-8");
   // System.out.println("服务端返回报文:"+new String(bytes));}
// //1. 模拟对象发送
 // User user = new User();
 // user.setUsername(“gblfy”);
 // user.setAge(28);
 // user.setPasswd(“123456”);
 // //2. 配置发送url
 // String url = “https://192…186.186:8888/postToJson”;
 // //3.发送前将对象转json处理
 // String reqXml = JSON.toJSONString(user);
 // //4.向指定url发送json格式的https协议报文
 // byte[] bytes = sendJsonToHttpsPost(url, reqXml, “utf-8”);
 // //5.对返回的报文解析
 // String resXml = new String(bytes);
 // JSONObject jsonObj = (JSONObject) JSON.parse(resXml);
 // //6.从解析的报文中获取指定的值
 // System.out.println(“服务端返回报文:” + jsonObj.getString(“username”));
 System.out.println(“服务端返回报文:” + jsonObj.getInt(“age”));
 // System.out.println(“服务端返回报文:” + jsonObj.getString(“passwd”));}