java.net.SocketException: Connection reset 异常处理
问题
oauth授权认证方式对接第三方平台,使用httpclient访问对方服务器,执行execute函数请求,java抛出异常,java.net.SocketException: Connection reset 这是双方握手建立连接后,开始write数据被服务器断开连接了,返回复位标志 RST关闭了连接并抛出了异常,感觉很奇怪,于是使用postman模拟表单提交请求获取对方令牌通过了,那可能是自己这边代码问题了,后来发现代码在请求http时是可用的,但请求https就会报错 connection rest ,查阅资料发现这是jdk的一个bug,已经在jdk8_141之后修复
所以,如果项目能升级到jdk8_141版本后,https请求的问题基本就能解决了,但公司项目使用的代码版本是jdk7_80的,如果为了我一个接口冒然升级那风险无疑是很大的。
解决
jdk7默认支持TLS是V1,jdk8后默认支持的是V1.2,所以在发起socket请求时指定协议为1.2,即可在不升级jdk的请求下解决这个问题
/** * * Description: 解决jdk 1.7版本访问https * @author willem * @date 2022/3/17 */ private static SSLConnectionSocketFactory getSslConnectionSocketFactory() { return new SSLConnectionSocketFactory(SSLContexts.createDefault()){ @Override protected void prepareSocket(SSLSocket socket) { String hostname = socket.getInetAddress().getHostName(); if (hostname.endsWith("www.baidu.com")){ socket.setEnabledProtocols(new String[] {"TLSv1.2"}); } else { socket.setEnabledProtocols(new String[] {"TLSv1", "TLSv1.1", "TLSv1.2"}); } } }; }
发送post请求
public static String post(String url, String client_id, String client_secret,String grant_type,String code,String redirect_uri,String scope) throws ClientProtocolException, IOException, NoSuchAlgorithmException { String jsonStr = ""; SSLConnectionSocketFactory sslsf = getSslConnectionSocketFactory(); CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); String requestBody = createRequestBody(client_id, client_secret,grant_type,code,redirect_uri,scope); HttpPost httpPost = new HttpPost(url); httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8"); StringEntity entity = new StringEntity(requestBody); httpPost.setEntity(entity); CloseableHttpResponse response = httpClient.execute(httpPost); jsonStr = EntityUtils.toString(response.getEntity()); return jsonStr; }
成功获取了第三方平台的令牌和授权,引起这个原因也有可能其他问题导致,如按本方案不能解决,请查阅其他资料。