JDK 17中如何替换sun.net.www.protocol.https.Handler?
替代JDK17中sun.net.www.protocol.https.Handler的可行方案
原JDK8运行正常的代码片段:
import javax.net.ssl.HttpsURLConnection; import sun.net.www.protocol.https.Handler; final URL resourceUrl = new URL(null, builder.addToURI(uri).toString(), new sun.net.www.protocol.https.Handler());升级至JDK17后触发错误:
Package 'sun.net.www.protocol.https' is declared in module 'java.base', which does not export it to the unnamed module
核心替代方案:使用标准URL构造函数,无需手动指定Handler
直接移除手动传入的内部Handler实例,改用Java标准的URL构造函数即可:
final URL resourceUrl = new URL(builder.addToURI(uri).toString());
原理说明
Java的URL类会自动根据URL字符串的协议前缀(如https://),从系统注册的协议处理器中匹配对应的默认实现,完全不需要手动实例化内部的Handler类。JDK8中允许直接调用内部类属于历史遗留场景,但从JDK9模块化开始,sun.*开头的内部包不再对外导出,因此必须切换到标准API。
若需自定义HTTPS配置的扩展方案
如果业务需要自定义SSL上下文、证书验证逻辑等,不要通过修改Handler实现,而是利用HttpsURLConnection的标准API配置:
// 1. 创建并初始化自定义SSLContext(示例,可根据需求调整) SSLContext sslContext = SSLContext.getInstance("TLSv1.3"); // 这里使用默认密钥/信任管理器,可替换为自定义实现 sslContext.init(null, null, new SecureRandom()); // 2. 获取连接并配置自定义SSL参数 URL resourceUrl = new URL(builder.addToURI(uri).toString()); HttpsURLConnection conn = (HttpsURLConnection) resourceUrl.openConnection(); // 设置自定义SSLSocketFactory conn.setSSLSocketFactory(sslContext.getSocketFactory()); // 若需自定义主机名验证逻辑 conn.setHostnameVerifier((hostname, session) -> { // 实现你的主机名校验逻辑 return hostname.equals("your-target-host.com"); }); // 3. 后续处理连接(如发送请求、读取响应) conn.setRequestMethod("GET"); // ... 其他业务操作
关键提示
sun.*开头的类属于Java内部API,官方从未承诺其跨版本兼容性,在JDK升级过程中随时可能被修改、迁移或移除,生产环境必须避免依赖这类非标准API,严格使用Java规范定义的公开接口。
内容的提问来源于stack exchange,提问作者NoName
相关产品推荐
相关产品推荐

