Java Http(s)URLConnection java.io.IOException:服务器返回 HTTP 响应代码:403

Posted

技术标签:

【中文标题】Java Http(s)URLConnection java.io.IOException:服务器返回 HTTP 响应代码:403【英文标题】:Java Http(s)URLConnection java.io.IOException: Server returned HTTP response code: 403 【发布时间】:2018-10-19 21:06:21 【问题描述】:

java.io.IOException:服务器返回 HTTP 响应代码:403 for http://www.budgetbottle.com/vivino.xml

当通过 Java 类 main 方法在本地 tomcat 服务器上运行时,此 URL 有效(返回内容),但在生产机器上的 tomcat 服务器上运行时抛出错误。

代码如下:

URL url = new URL("http://www.budgetbottle.com/vivino.xml");    
HttpURLConnection urlcon = (HttpURLConnection) url.openConnection();
urlcon.addRequestProperty("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
// System.setProperty("http.agent", "");
System.setProperty("http.agent", "Chrome");

// urlcons.setRequestProperty("Content-Language", "en-US");
// urlcons.setUseCaches(false);
// urlcons.setDoInput(true);
// urlcons.setDoOutput(true);

我已经应用了该论坛上提出的类似问题提供的解决方案,但没有解决方案。

更新: 我刚刚注意到,wget 实用程序也会在生产系统中引发相同的错误,而在本地系统中没有问题。请注意使用了 User-Agent 等选项

这是系统特定的错误吗?

【问题讨论】:

你试过'budgetbottle.com/vivino.xml'吗?包含https 是的@HarneetSingh,我尝试了budgetbottle.com/vivino.xml,但它也抛出了同样的异常 【参考方案1】:

可能是您的生产服务器以某种方式限制了网络连接(所有 http/https 连接尝试都重定向到返回“访问被拒绝”的强制代理)?

您是否能够从您的生产环境访问任何其他外部站点?

【讨论】:

感谢@juha-laiho 的建议。是的,我可以从我的生产环境访问外部网站。【参考方案2】:

生产服务器很可能在 Apache HTTPD 服务器后面运行,该服务器将请求代理到 Tomcat 服务器。这种设置在某些部署中受到青睐,原因如下:

它允许将应用程序的静态服务元素复制到 Apache HTTPD 处理端,其中 Apache HTTPD 在从磁盘提供静态文件方面通常比 Tomcat 快得多。 它只允许转发“有效”请求,从而减少 Tomcat 的负载。 它允许不转发任何可能重新配置 Tomcat 中的应用程序部署或配置的请求,即使有人意外部署了 Tomcat 的 Web 管理工具 只要请求来自一组受信任的 Internet 地址,就可以使用 Web 管理工具。

还有很多系统管理员可能感兴趣的附加项目,促使他们在 Apache HTTPD 后面部署 Tomcat。

在至少一种情况下,它还可能允许 Apache HTTPD 在将请求转发到 Tomcat 之前在 HTTPD 层进行质询和响应身份验证。

在继续之前,您需要更好地了解您的生产部署。然后您需要尝试在您的开发环境中更准确地重新创建它。

【讨论】:

感谢@edwin,我的待办事项列表中也有这种方法。我正在尝试设置具有相同配置的新机器。【参考方案3】:

我使用了下面的代码,对我来说效果很好。您的服务器上是否有某种速率限制或 IP 禁止系统,可能会阻止您的连接?

    URL url = new URL("http://www.budgetbottle.com/vivino.xml");
    HttpURLConnection urlcon = (HttpURLConnection) url.openConnection();
    urlcon.addRequestProperty("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
    System.setProperty("http.agent", "Chrome");
    BufferedReader reader = new BufferedReader(new InputStreamReader(urlcon.getInputStream()));
    StringBuilder sb = new StringBuilder();
    String line = null;
    while ((line = reader.readLine()) != null)
    
        sb.append(line + "\n");
    
    System.out.println(sb.toString());

【讨论】:

我尝试了您的代码,该代码在我的本地系统上运行良好,但在生产系统上却失败了。仅供参考,两个系统的 Java 版本相同 我可以得到堆栈跟踪和抛出的错误消息吗?另外,您是否可以在生产服务器上提供该请求的日志? 这里是堆栈跟踪:java.io.IOException:服务器返回 HTTP 响应代码:403 for URL:budgetbottle.com/vivino.xml at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection. java:1627) 在 com.batch.Spider.main(Spider.java:2041) 您是否尝试过不同的用户代理,因为我得到 403 的唯一方法是没有用户代理。我也使用java.net.HttpURLConnection 而不是sun.new.www.protocol.http.HttpURLConnection

以上是关于Java Http(s)URLConnection java.io.IOException:服务器返回 HTTP 响应代码:403的主要内容,如果未能解决你的问题,请参考以下文章

Java URLConnection实现HTTP的GET/POST

查询网页时Java传递URLConnection参数

如何在java中重置URLConnection?

java中的URLConnection如何重用池中的连接

java之URL(URL,URLConnection)实例

Java实现多线程下载 URL以及URLConnection