9

我有一个网站,其 URL 以“http://”开头,但这给了我一个例外消息 - 不支持的协议:https。该站点是否有可能使用 HTTPS 协议,其 URL 仍然以“http://”而不是“https://”开头。

public ActionForward executeAction(ActionMapping mapping, ActionForm form,
              HttpServletRequest request, HttpServletResponse response)
      throws Exception {

    ActionForward forward = mapping.findForward(Constants.SUCCESS);
    String link = "http://abc.fgh.jkl.mno";
    URL thisURL;
    HttpURLConnection conn = null;
    try {
        thisURL = new URL(link);
        conn = (HttpURLConnection) thisURL.openConnection();
        System.out.println(conn.getResponseCode());
        System.out.println(conn.getResponseMessage());
        } catch (Exception ex) {
        ex.printStackTrace();
    }
    return forward;
}       

堆栈跟踪

java.net.ProtocolException: Unsupported protocol: https'
    at weblogic.net.http.HttpClient.openServer(HttpClient.java:342)
    at weblogic.net.http.HttpClient.New(HttpClient.java:238)
    at weblogic.net.http.HttpURLConnection.connect(HttpURLConnection.java:172)
    at weblogic.net.http.HttpURLConnection.followRedirect(HttpURLConnection.java:643)
    at weblogic.net.http.HttpURLConnection.getInputStream(HttpURLConnection.java:422)
    at           weblogic.net.http.SOAPHttpURLConnection.getInputStream(SOAPHttpURLConnection.java:36)
    at weblogic.net.http.HttpURLConnection.getResponseCode(HttpURLConnection.java:947)
    at com.cingular.cscape.da.struts.action.thisAction.executeAction(thisAction.java:56)
    at com.cingular.cscape.da.struts.action.BaseAction.execute(BaseAction.java:300)
    at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421)
    at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:226)
    at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1164)
    at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:397)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:292)
    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
    at org.extremecomponents.table.filter.AbstractExportFilter.doFilter(AbstractExportFilter.java:53)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3496)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(Unknown Source)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2180)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2086)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1406)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)                  
4

3 回答 3

13

您是否注意到异常消息中不匹配的撇号?

java.net.ProtocolException: Unsupported protocol: https'
                                                       ^

更新:看起来这个撇号只是 WebLogic HttpClient 如何打印此异常的一个怪癖。

在聊天会话中发现了 Asker 的根本问题:他正在访问一个 http:// URL,该 URL 将他重定向到一个 https:// URL。该 https 地址的网络服务器正在提供他的 JRE/HttpClient 不信任的证书。

实际的异常应该是 SSLKeyException。我认为 WebLogic HttpClient 将此问题误报为不受支持的协议问题。我认为核心问题是:

<Warning> <Security> <BEA-090477> javax.net.ssl.SSLKeyException: [Security:090477] Certificate chain received from www.X.com - nnn.nnn.nnn.nnn was not trusted causing SSL handshake failure.

这是提问者在直接访问 https:// URL(而不是通过重定向链)时看到的消息。

默认情况下,Java 的 Http[s]URLConnection 会自动且安静地跟随重定向。如果您对重定向到的位置感到好奇,请尝试以下代码:

connection.setInstanceFollowRedirects(false);
String location = connection.getHeaderField("Location");
System.out.println("Redirected to: " + location);

请注意,您被重定向到的 URL 也可能会将您重定向到其他地方,并且一直持续到http.maxRedirects次。重定向可能以这种方式“链接”。如果他们确实链接,您将需要继续跟踪重定向,直到您到达不发出重定向的 URL。这就是 URL 连接最终在setInstanceFollowRedirects(true).

此外,我在 sun.net.www.protocol.http.HttpURLConnection 中发现了一些代码,这似乎表明HttpURLConnection 可能不支持切换协议(HTTP -> HTTPS)作为其自动重定向以下逻辑的一部分

private boolean followRedirect() throws IOException {
    // ... [snip] ...
    if (!url.getProtocol().equalsIgnoreCase(locUrl.getProtocol())) {
        return false;
    // ... [snip] ...

WebLogic 有自己的(不同的)HttpURLConnection 实现,但它可能包含类似的逻辑来防止协议切换。因此,即使提问者解决了他的证书信任问题,他仍然可能无法使用 HttpURLConnection 自动跟踪从 HTTP 到 HTTPS 的重定向链。一种解决方法是手动使用setInstanceFollowRedirects(false)和遵循重定向。或者直接访问 HTTPS 站点。

于 2013-01-04T17:27:52.950 回答
5

HTTP 是在 TCP/IP 上运行的协议。HTTPS 是基于安全套接字的 HTTP(SSL 或更新的 TLS)。现在,什么是 URL?它是一个标识资源的字符串,大致如下:

scheme://host:port/path/to/resource

请注意,有时我们不指定端口号,因为某些协议具有关联的众所周知的端口号。HTTP 是 80,HTTPS 是 443,所以这些数字是隐含的。但是,请注意,您可以将服务器套接字绑定到您想要的任何端口:如果您告诉 HTTP 服务器程序将其套接字绑定到 localhost 上的端口 8273,它会很乐意这样做。

就是说,在您的情况下,消息显示“不支持的协议:https ”。我们可以在这里猜测,但是我认为您传递给 URL 的字符串不是您想的那样。

于 2013-01-04T17:09:37.297 回答
0

另一种可能性是 HTTP 地址以 3xx 重定向响应响应 HTTPS URL,您的客户端尝试遵循该 URL,但不支持该 URL。您可以通过 tcpdump 或 wireshark 捕获网络流量。

有这么多支持 HTTPS 的 Java HTTP 客户端库,为什么不切换到其中之一呢?

于 2013-01-05T12:02:00.477 回答