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 + "\n"); } // 释放资源 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(); }