java JDK1.7的HTTPConnection请求Connection reset问题解决
程序员文章站
2022-07-14 21:15:05
...
java JDK1.7的HTTPConnection请求Connection reset问题解决
这几天有个接口,发现有个奇怪的问题,之前好的突然间出现httpconnection的链接请求错误
错误代码如下:
Caused by: java.net.SocketException: Connection reset at java.net.SocketInputStream.read(SocketInputStream.java:189) at java.net.SocketInputStream.read(SocketInputStream.java:121) at sun.security.ssl.InputRecord.readFully(InputRecord.java:312) at sun.security.ssl.InputRecord.read(InputRecord.java:350) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893)
刚开始一点头绪都没有,后来慢慢研究发现,原来是客户更新了https证书,该证书不在支持TLSV1.0了导致的。而我们服务端的JDK版本比较久,是JDK1.7的,1.7默认使用的TLS版本是1.0,所以才会有这个问题
,需要在我们HTTPConnection中增加对默认tls的设置,才可以正常访问接口
加入下面代码:
/** * 证书信任 */ private static void trustAllHttpsCertificates() { try { javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1]; javax.net.ssl.TrustManager tm = new miTM(); trustAllCerts[0] = tm; javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("TLSv1.2");//默认jdk1.7是使用tlsv1.0协议,这里采用1.2 sc.init(null, trustAllCerts, null); javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch(Exception e) { e.printStackTrace(); } } static class miTM implements javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) { return true; } public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) { return true; } public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException { return; } public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) throws java.security.cert.CertificateException { return; } }
看到tlsv1.2的地方,改一下。然后在你原来connection链接请求地方调用上面代码方法
public static String getHttpContent(String url, String charSet) { //该部分必须在获取connection前调用 HostnameVerifier hv = new HostnameVerifier() { public boolean verify(String urlHostName, SSLSession session) { System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost()); return true; } }; trustAllHttpsCertificates(); //////////在您connection之前调用一下就可以了 HttpURLConnection connection = null; String content = ""; try { URL address_url = new URL(url); connection = (HttpURLConnection) address_url.openConnection(); connection.setRequestProperty("Content-type", "text/html"); connection.setRequestProperty("Accept-Charset", charSet); connection.setRequestProperty("contentType", charSet); connection.setDoInput(true); connection.setDoOutput(true); // connection.setRequestMethod("GET"); //设置访问超时时间及读取网页流的超市时间,毫秒值 System.setProperty("sun.net.client.defaultConnectTimeout","20000"); System.setProperty("sun.net.client.defaultReadTimeout", "20000");
希望对后来的人有帮助就好。特此留帖!