• Https通信工具类


      记录一个在微信开发中用到的https通信工具类,以后会用到的。

      

      用于https通信的证书信任管理器

    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    
    import javax.net.ssl.X509TrustManager;
    
    /**
     * 证书信任管理器(用于https请求)
     */
    public class MyX509TrustManager implements X509TrustManager {  
        /**
         * create by yyc 2017年6月27日上午10:24:49
         */
        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
            // TODO Auto-generated method stub
            
        }
    
        /**
         * create by yyc 2017年6月27日上午10:24:49
         */
        @Override
        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
            // TODO Auto-generated method stub
            
        }
    
        /**
         * create by yyc 2017年6月27日上午10:24:49
         */
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            // TODO Auto-generated method stub
            return null;
        }  
    } 

       httpRequest方法,就是用于https通信的,方法传入请求的url,请求的方式(如:GET,POST),请求发送的数据等

    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.net.ConnectException;
    import java.net.URL;
    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 org.apache.commons.httpclient.HttpStatus;
    
    
    /**
     * 编写一个用于发起https请求的工具类WeiXinNetWorkUtil 访问网络用到的工具类
     */
    public class WeiXinNetWorkUtil {
        /**
         * 发起Https请求
         * 
         * @param reqUrl
         *            请求的URL地址
         * @param requestMethod
         *            请求的方法
         * @param outputStr
         *            提交的数据
         * @return 响应后的字符串(可能是json、xml或其它,但都是String型的) httpRequest方法是请求一个https地址,
         *         参数requestMethod为字符串“GET”或者“POST”,传null或者“”默认为get方式,
         *         参数outputStr为一个要提交的字符串,不为""或null时,requestMethod为“POST”。
         */
        public static String httpRequest(String reqUrlString, String requestMethod, String outputStr) {
            URL url;
            HttpsURLConnection conn = null;
            InputStream inputStream = null;
            InputStreamReader inputStreamReader = null;
            BufferedReader bufferReader = null;
            StringBuffer resultData = new StringBuffer();
            try {
                // 创建url资源
                url = new URL(reqUrlString);
                // 建立http连接
                conn = (HttpsURLConnection) url.openConnection();
    
                // 创建SSLContext对象,并使用我们指定的信任管理器初始化
                TrustManager[] tm = { new MyX509TrustManager() };
    
                SSLContext ctx = SSLContext.getInstance("SSL", "SunJSSE");
                ctx.init(null, tm, new java.security.SecureRandom());
    
                conn.setSSLSocketFactory(ctx.getSocketFactory());
                conn.setHostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String arg0, SSLSession arg1) {
                        return true;
                    }
                });
    
                conn.setDoInput(true); // 允许输入流,即允许下载
    
                conn.setDoOutput(true); // 允许输出流,即允许上传
                conn.setUseCaches(false); // 是否使用缓冲
                if (null != requestMethod && !"".equals(requestMethod)) {
                    conn.setRequestMethod(requestMethod); // 使用指定的方式
                } else {
                    conn.setRequestMethod("GET"); // 使用get请求
                }
    
                // 当有数据需要提交时
                if (null != outputStr && !"".equals(outputStr)) {
                    OutputStream outputStream = conn.getOutputStream();
                    // 注意编码格式,防止中文乱码
                    outputStream.write(outputStr.getBytes("UTF-8"));
                    outputStream.flush();
                    // 释放资源
                    if (outputStream != null) {
                        outputStream.close();
                        outputStream = null;
                    }
                }
    
                conn.connect();// 开始连接请求
    
                // 请求返回的状态
                if (conn.getResponseCode() == HttpStatus.SC_OK) {
    
                    System.out.println("https网络连接成功,返回码:"+conn.getResponseCode());
                    inputStream = conn.getInputStream(); // 获取输入流
                    inputStreamReader = new InputStreamReader(inputStream);
                    bufferReader = new BufferedReader(inputStreamReader);
                    String inputLine;
                    while ((inputLine = bufferReader.readLine()) != null) {// 将返回的输入流转换成字符串
                        resultData.append(inputLine + "
    ");
                    }
    
                    // 释放资源
                    if (bufferReader != null) {
                        bufferReader.close();
                        bufferReader = null;
                    }
                    if (inputStreamReader != null) {
                        inputStreamReader.close();
                        inputStreamReader = null;
                    }
                    if (inputStream != null) {
                        inputStream.close();
                        inputStream = null;
                    }
                }else{
                    System.out.println("https网络连接错误,错误码:"+conn.getResponseCode());
                }
            } catch (ConnectException ce) {
                System.err.println("Weixin server connection timed out.");
                ce.printStackTrace();
            } catch (Exception e) {
                System.err.println("https request error.");
                e.printStackTrace();
            } finally {
                // 断开网络连接
                conn.disconnect();
            }
            
            return resultData.toString();
        }
    
    }

     20170822发现通过上述方式发送数据,对方在通过如下方式不能接收

        byte[] bytes = null;
            try {
                final ServletInputStream inputStream = request.getInputStream();
                ServletInputStream iii = request.getInputStream();
                int len = request.getContentLength();
                bytes = new byte[len];
                iii.read(bytes, 0, len);
            } catch (IOException e) {
                e.printStackTrace();
            }
            String string = new String (bytes);
            System.out.println(string);

    解决方法:发送数据时,不用OutputStream来将数据放到输出流中 ,用它的一个子类(DataOutputStream)就可以。

    如下:

    OutputStream outputStream = conn.getOutputStream();
                    // 注意编码格式,防止中文乱码
                    DataOutputStream out=new DataOutputStream(outputStream);
                    out.write(outputStr.getBytes("UTF-8"));
    //                outputStream.write(outputStr.getBytes("UTF-8"));
                    outputStream.flush();
                    out.flush();
                    // 释放资源
                    if (null != outputStream){
                        outputStream.close();
                    }
                    if (null != out){
                        out.close();
                    }
  • 相关阅读:
    node-webkit 笔记
    CEF 相关资料
    输出重定向
    FindProcDLL::FindProc 和 KillProcDLL::KillProc,必须使用WPF x86编译出来的程序
    wpf xaml inlines
    Gradle 笔记
    Android手机的 storage
    SpringMVC 工作原理详解
    SpringMVC 面试题
    18、多线程 (线程安全、线程同步、等待唤醒机制、单例设计模式)
  • 原文地址:https://www.cnblogs.com/hyyq/p/7089040.html
Copyright © 2020-2023  润新知