解决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;
    }
}
相关推荐
古法安卓9 分钟前
Android-重启流程源码解析
android·java·android studio
清水白石00820 分钟前
Python 类型设计深度解析:TypedDict 能否替代 dataclass?从 JSON 数据边界到 API 设计的最佳实践
java·python·json
晊晌_h35 分钟前
嵌入式从0到精通——线程
java·开发语言·jvm
一木 之林42 分钟前
五、C++ 新特性、关键字与编译原理(进阶)(二)
java·开发语言·c++
洋不写bug1 小时前
绕过权限检查,访问修改私有属性,反射,枚举,lambda
java·枚举·lambda·反射
evans在进步1 小时前
Java 常用设计模式入门:建造者、工厂、单例、外观与代理
java·python·设计模式
lisin-lee-cooper1 小时前
【leetcode658】有序数组找出k个最接近x的数
java·数据结构·算法
MyFreeIT1 小时前
Let‘s Encrypt SSL 製作免費證書
网络协议·https·ssl
sunburn-1 小时前
Java堆(Heap)详解与实战教学
java·开发语言·数据结构·ide·算法
Kyrie_kk1 小时前
Java--TimeUnit时间单位枚举类(时间单位规范)
java·后端