解决JDK7调用https报:java.net.SocketException: Connection reset错误

原因分析:

大多数现代的 HTTPS 连接将使用 TLS 1.2协议 或 TLS 1.3 协议,具体取决于服务器和客户端支持的版本以及其之间的协商,而JDK7及以下版本默认使用是TLS v1协议,所以在调用HTTPS接口时,会出现java.net.SocketException: Connection reset报错;

下面是不同JDK版本的默认TLS协议:

java 复制代码
JDK 6
    SSL v3
    TLS v1(默认)
    TLS v1.1(JDK6 update 111 及以上)
JDK 7
    SSLv3
    TLS v1(默认)
    TLS v1.1
    TLS v1.2
JDK 8
    SSL v3
    TLS v1
    TLS v1.1
    TLS v1.2(默认)

解决方案:

手动设置TLS协议为v1.2版本,下面我提供了POST+JSON+用户认证请求(如果不需要用户认证的,可以去掉)代码示例供参考:

java 复制代码
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class HttpClientUtils {


    public static void main(String[] args) {
        try {
            String path = "https://XXXXXXXXXX";
            JSONObject param = new JSONObject();
            param.put("param1", "参数1");
            param.put("param2", "参数2");
            String resStr = HttpClientUtils.sendHttpsPostTLSAdd(path, param.toJSONString(), "用户账号", "用户密码", "UTF-8");
            System.out.println(resStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * post请求,设置TLS协议
     * @param url
     * @param json
     * @param username 用户名
     * @param password 密码
     * @param charSet 请求编码(UTF-8)
     * @return
     * @throws Exception
     */
    public static String sendHttpsPostTLSAdd(String url, String json, String username, String password, String charSet) throws Exception {
        // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
        X509TrustManager trustManager = new X509TrustManager() {
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }

            @Override
            public void checkClientTrusted(X509Certificate[] arg0, String arg1)
                    throws CertificateException {

            }

            @Override
            public void checkServerTrusted(X509Certificate[] arg0, String arg1)
                    throws CertificateException {

            }

        };

        // 设置TLS协议版本为TLSv1.2
        SSLContext sc = SSLContext.getInstance("TLSv1.2");
        sc.init(null, new TrustManager[] { trustManager }, null);
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sc);

        // 得到httpClient对象
        CloseableHttpClient httpClient = null;
        HttpPost httpPost = null;
        String result = null;
        httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        httpPost = new HttpPost(url);

        // 用户认证
        String authString = username + ":" + password;
        String encodedAuthString = Base64.encodeBase64String(authString.getBytes());
        httpPost.setHeader("Authorization", "Basic " + encodedAuthString);

        // 推送配置
        StringEntity entity = new StringEntity(json, charSet);
        entity.setContentEncoding(charSet); // 设置编码格式
        entity.setContentType("application/json"); // 设置JSON请求
        httpPost.setEntity(entity);
        // 执行
        HttpResponse response = httpClient.execute(httpPost);
        if (response != null) {
            HttpEntity resEntity = response.getEntity();
            if (resEntity != null) {
                result = EntityUtils.toString(resEntity, charSet);
            }
        }

        return result;
    }
}
相关推荐
皮皮林5518 小时前
Java性能调优黑科技!1行代码实现毫秒级耗时追踪,效率飙升300%!
java
冰_河8 小时前
QPS从300到3100:我靠一行代码让接口性能暴涨10倍,系统性能原地起飞!!
java·后端·性能优化
桦说编程11 小时前
从 ForkJoinPool 的 Compensate 看并发框架的线程补偿思想
java·后端·源码阅读
躺平大鹅13 小时前
Java面向对象入门(类与对象,新手秒懂)
java
初次攀爬者14 小时前
RocketMQ在Spring Boot上的基础使用
java·spring boot·rocketmq
花花无缺14 小时前
搞懂@Autowired 与@Resuorce
java·spring boot·后端
Derek_Smart15 小时前
从一次 OOM 事故说起:打造生产级的 JVM 健康检查组件
java·jvm·spring boot
NE_STOP16 小时前
MyBatis-mybatis入门与增删改查
java
孟陬19 小时前
国外技术周刊 #1:Paul Graham 重新分享最受欢迎的文章《创作者的品味》、本周被划线最多 YouTube《如何在 19 分钟内学会 AI》、为何我不
java·前端·后端