解决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;
    }
}
相关推荐
小曲程序4 分钟前
vue3 封装request请求
java·前端·typescript·vue
陈王卜22 分钟前
django+boostrap实现发布博客权限控制
java·前端·django
小码的头发丝、22 分钟前
Spring Boot 注解
java·spring boot
java亮小白199727 分钟前
Spring循环依赖如何解决的?
java·后端·spring
飞滕人生TYF34 分钟前
java Queue 详解
java·队列
武子康1 小时前
大数据-230 离线数仓 - ODS层的构建 Hive处理 UDF 与 SerDe 处理 与 当前总结
java·大数据·数据仓库·hive·hadoop·sql·hdfs
武子康1 小时前
大数据-231 离线数仓 - DWS 层、ADS 层的创建 Hive 执行脚本
java·大数据·数据仓库·hive·hadoop·mysql
苏-言1 小时前
Spring IOC实战指南:从零到一的构建过程
java·数据库·spring
界面开发小八哥1 小时前
更高效的Java 23开发,IntelliJ IDEA助力全面升级
java·开发语言·ide·intellij-idea·开发工具
草莓base1 小时前
【手写一个spring】spring源码的简单实现--容器启动
java·后端·spring