使用HttpsURLConnection时默认为HttpsURLConnectionOLDImpl异常ClassCastException

使用HttpsURLConnection时默认为HttpsURLConnectionOLDImpl异常ClassCastException

一、问题描述:

在测试环境是可以正常的发送到指定的https地址上,而在生产环境上访问时会抛出以下错误:
java.lang.ClassCastException:com.sun.net.ssl.internal.www.protocol.https.HttpsURLConnectionOLDImpl cannot be case to javax.net.ssl.HttpsURLConnection.

二、问题分析:(有待补充)
几乎同样的问题出现在优快云的帖子中,没什么有用的回答:
http://bbs.youkuaiyun.com/topics/380110416

三、问题解决:
从谷歌中找到一篇相关的文章:
http://stackoverflow.com/questions/3038026/using-java-class-httpsurlconnection
并从中找到解决方法:
java.net.URL wsURL = new URL(null, url,new sun.net.www.protocol.https.Handler());

四、扩展延伸:
另外,百度到几篇相关的文章:
http://xmuzyq.iteye.com/blog/1162688
http://java.chinaitlab.com/base/821109.html

JDK中api:java.net.URL(String protocol, String host, int port, String file)


五、备注:

感谢互联网、强大的群众智慧

<think>嗯,用户问的是如何使用HttpsURLConnection实现HTTPS通讯。首先,我需要回忆一下Java中处理HTTPS请求的基本流程。HttpsURLConnection是Java标准库中的一个类,用于处理HTTPS请求,但和HTTP不同,HTTPS需要处理SSL/TLS证书相关的验证。 首先,可能需要先创建一个URL对象,然后打开连接,转换成HttpsURLConnection。然后设置请求方法,比如GET或POST,接着处理输入输出流。不过HTTPS涉及到证书的问题,用户可能需要了解如何处理自签名证书或者绕过证书验证,这在开发测试阶段比较常见,但生产环境不建议这么做。 然后,用户可能不知道如何信任所有证书,这候需要设置一个信任所有证书的TrustManager。不过需要注意这样做不安全,只能用于测试。具体步骤可能是创建SSLContext,使用自定义的TrustManager,然后设置到HttpsURLConnection中。 另外,客户端证书的情况可能也需要考虑,但用户没有提到,可能暂不需要。还要处理主机名验证的问题,默认情况下会验证主机名是否与证书匹配,如果不匹配会报错,这候可能需要自定义HostnameVerifier,比如接受所有主机名,同样不安全但测试用。 然后,代码示例的大致步骤应该是:创建URL对象,打开连接,设置请求方法,设置HostnameVerifier和SSLSocketFactory,处理响应流。同异常处理也很重要,比如SSLHandshakeException,可能由证书问题引起。 可能需要分两种情况,一种是默认的信任所有证书(不推荐),另一种是配置信任特定证书。用户可能更关注前者,因为后者需要导入证书等步骤更复杂。还要提醒用户生产环境中应该使用正确的证书配置,而不是绕过验证。 另外,Java 8和更新的版本可能会有不同的行为吗?比如默认启用的TLS版本,可能需要显式设置。还有,如何处理POST请求,设置请求头,比如Content-Type,处理输出流等,可能需要补充。 总结回答的结构:先介绍HttpsURLConnection的基本用法,然后说明如何处理证书验证和主机名验证,提供示例代码,并强调安全注意事项。可能还需要提到SSLContext的初始化和自定义TrustManager的实现。</think>以下是使用`HttpsURLConnection`实现HTTPS通讯的详细步骤和注意事项: --- ### 一、基本流程 ```java import javax.net.ssl.HttpsURLConnection; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; public class HttpsExample { public static void main(String[] args) throws Exception { // 1. 创建URL对象 URL url = new URL("https://example.com"); // 2. 打开HTTPS连接 HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); // 3. 设置请求方法 conn.setRequestMethod("GET"); // 4. 处理响应 try (BufferedReader reader = new BufferedReader( new InputStreamReader(conn.getInputStream()))) { String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } } } ``` --- ### 二、处理SSL证书验证 #### 场景1:信任所有证书(仅测试环境使用) ```java import javax.net.ssl.*; public class TrustAllCertificates { public static void disableCertificateValidation() throws Exception { // 创建信任所有证书的TrustManager TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) { } public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) { } } }; // 初始化SSLContext SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); // 禁用主机名验证 HttpsURLConnection.setDefaultHostnameVerifier( (hostname, session) -> true); } } ``` #### 使用方式 ```java public static void main(String[] args) throws Exception { TrustAllCertificates.disableCertificateValidation(); // 先禁用证书验证 // 后续执行常规HTTPS请求... } ``` #### 场景2:信任特定证书(生产推荐) 需将证书导入Java信任库: ```bash keytool -import -alias example -keystore cacerts -file server.cer ``` --- ### 三、完整示例(包含POST请求) ```java import javax.net.ssl.HttpsURLConnection; import java.io.*; import java.net.URL; import java.nio.charset.StandardCharsets; public class HttpsPostExample { public static void main(String[] args) throws Exception { URL url = new URL("https://example.com/api"); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); // 设置请求属性 conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/json"); conn.setDoOutput(true); // 发送请求体 String jsonBody = "{\"key\":\"value\"}"; try (OutputStream os = conn.getOutputStream()) { os.write(jsonBody.getBytes(StandardCharsets.UTF_8)); } // 处理响应 try (BufferedReader br = new BufferedReader( new InputStreamReader(conn.getInputStream()))) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } } } ``` --- ### 四、关键注意事项 1. **证书安全** - 生产环境必须使用有效证书,避免关闭证书验证 - 自签名证书需通过`keytool`导入JVM信任库 2. **协议配置** ```java // 强制使用TLSv1.2(针对老旧系统) System.setProperty("https.protocols", "TLSv1.2"); ``` 3. **超设置** ```java conn.setConnectTimeout(5000); // 5秒连接超 conn.setReadTimeout(10000); // 10秒读取超 ``` 4. **异常处理** - 捕获`SSLHandshakeException`处理证书错误 - 处理`IOException`应对网络问题 --- ### 五、最佳实践建议 - 使用Apache HttpClient或OkHttp等成熟库代替原生实现 - 定期更新JRE中的根证书 - 通过`SSLContext`自定义安全策略,优先选择更安全的密码套件 > 通过合理配置,`HttpsURLConnection`能够满足基本HTTPS通讯需求,但在复杂场景下建议使用专业HTTP客户端库。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值