【问题标题】:URLConnection FileNotFoundException for non-standard HTTP port sources非标准 HTTP 端口源的 URLConnection FileNotFoundException
【发布时间】:2009-06-02 20:08:45
【问题描述】:

我试图使用 Apache Ant Get task 来获取我们公司另一个团队生成的 WSDL 列表。他们将它们托管在http://....com:7925/services/ 上的 weblogic 9.x 服务器上。我可以通过浏览器访问该页面,但是当尝试将页面复制到本地文件进行解析时,get 任务给了我一个 FileNotFoundException。我仍然能够(使用 ant 任务)获得一个没有用于 HTTP 的非标准端口 80 的 URL。

我查看了 Ant 源代码,并将错误缩小到 URLConnection。似乎 URLConnection 无法识别数据是 HTTP 流量,因为它不在标准端口上,即使协议被指定为 HTTP。我使用 WireShark 嗅探了流量,页面通过网络正确加载,但仍然收到 FileNotFoundException。

这是一个您将看到错误的示例(更改了 URL 以保护无辜者)。 connection.getInputStream();

上抛出错误
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

    public class TestGet {
    private static URL source; 
    public static void main(String[] args) {
        doGet();
    }
    public static void doGet() {
            try {
            source = new URL("http", "test.com", 7925,
                    "/services/index.html");
            URLConnection connection = source.openConnection();
            connection.connect();
            InputStream is = connection.getInputStream();
        } catch (Exception e) {
            System.err.println(e.toString());
        }
    }

}

【问题讨论】:

  • 现在我假设它是一种类型,但您的链接位于端口 7924 并且您的代码正在查看端口 7925
  • 是的,这是一个错字,现在更正了,谢谢。

标签: java ant urlconnection


【解决方案1】:

对我的 HTTP 请求的响应返回了状态代码 404,当我调用 getInputStream() 时,这导致了 FileNotFoundException。我仍然想阅读响应正文,所以我不得不使用不同的方法:HttpURLConnection#getErrorStream()

这是 getErrorStream() 的 JavaDoc sn-p:

返回错误流,如果 连接失败,但服务器已发送 还是有用的数据。典型的 例如,当一个 HTTP 服务器 以 404 响应,这将导致 要抛出的 FileNotFoundException 在连接中,但服务器发送了一个 带有建议的 HTML 帮助页面 怎么办。

使用示例:

public static String httpGet(String url) {
    HttpURLConnection con = null;
    InputStream is = null;
    try {
        con = (HttpURLConnection) new URL(url).openConnection();
        con.connect();

        //4xx: client error, 5xx: server error. See: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html.
        boolean isError = con.getResponseCode() >= 400;
        //In HTTP error cases, HttpURLConnection only gives you the input stream via #getErrorStream().
        is = isError ? con.getErrorStream() : con.getInputStream();

        String contentEncoding = con.getContentEncoding() != null ? con.getContentEncoding() : "UTF-8";
        return IOUtils.toString(is, contentEncoding); //Apache Commons IO
    } catch (Exception e) {
        throw new IllegalStateException(e);
    } finally {
        //Note: Closing the InputStream manually may be unnecessary, depending on the implementation of HttpURLConnection#disconnect(). Sun/Oracle's implementation does close it for you in said method.
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                throw new IllegalStateException(e);
            }
        }
        if (con != null) {
            con.disconnect();
        }
    }
}

【讨论】:

  • 这很有帮助,但它只是一个模糊的 400 错误页面。我正在使用 graph.facebook.com/me/photos 并且在浏览器中它可以工作,除非您尝试通过 Web 开发人员插件查看标题。因此,输入流似乎以某种方式创建了一个新请求,这没有任何意义......更多时间来解决这个问题......不过感谢 geterrorstream 提示。
  • 它有效。检查响应代码,然后相应地获取 getErrorStream() 或 getInputStream()。在这种情况下应该提供代码sn-p。
  • 检查响应代码对我有很大帮助。现在我没有找到 FileNotFoundException..thanks @bcody
  • 这对我帮助很大,因为我发现错误出现在我的标题中。但多亏了这一点,我也意识到如果我只是查看服务器协议,我可以找到更多关于 FileNotFoundException 的信息。只是对像我这样的其他新手的建议。
  • 谢谢 这对我很有帮助。
【解决方案2】:

这是一个旧线程,但我遇到了类似的问题并找到了此处未列出的解决方案。

我在浏览器中正常接收页面,但是当我尝试通过 HttpURLConnection 访问它时得到 404。我试图访问的 URL 包含一个端口号。当我在没有端口号的情况下尝试它时,我通过 HttpURLConnection 成功获得了一个虚拟页面。所以看起来非标准端口是问题所在。

我开始认为访问受到限制,在某种意义上确实如此。我的解决方案是我需要告诉服务器用户代理,并且我还指定了我期望的文件类型。我正在尝试读取 .json 文件,因此我认为文件类型也可能是必要的规范。

我添加了这些行,它终于奏效了:

httpConnection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
httpConnection.setRequestProperty("Accept","*/*");

【讨论】:

  • 这正是我面临的问题。您的解决方案有所帮助。非常感谢。
【解决方案3】:

检查服务器返回的响应码

【讨论】:

  • 我正在用 Firefox 检查它。不过,你是对的。问题是服务器向 Java 代码返回 404 代码,但随后显示可用 WSDL 的索引,因此向 Firefox 回复 200 OK 状态代码。我认为 XFire 的默认行为是在出现 404 错误时显示 WSDL 列表。
【解决方案4】:

我知道这是一个旧线程,但我找到了一个未在此处列出的解决方案。

我试图从端口 8080 上的 J2EE servlet 中提取 json 格式的数据,但收到未找到文件错误。我能够从端口 80 上运行的 php 服务器中提取相同的 json 数据。

事实证明,在 servlet 中,我需要将 doGet 更改为 doPost。

希望这对某人有所帮助。

【讨论】:

    【解决方案5】:

    你可以使用OkHttp:

    OkHttpClient client = new OkHttpClient();
    
    String run(String url) throws IOException {
      Request request = new Request.Builder()
          .url(url)
          .build();
    
      Response response = client.newCall(request).execute();
      return response.body().string();
    }
    

    【讨论】:

      【解决方案6】:

      我已经在本地尝试过 - 使用提供的代码 - 我没有收到 FileNotFoundException,除非服务器返回状态 404 响应。

      您确定要连接到要连接的网络服务器吗?您是否有机会连接到不同的网络服务器? (我注意到代码中的端口号与链接中的端口号不匹配)

      【讨论】:

      • 我正在测试的服务器给了我一个 200 状态码。上面的代码示例没有有效的 URL,因为我不知道公共的非 80 端口 HTTP 服务器。
      • 402 也给出了这个例外。
      • 另外 503 给出了这个例外(我的由反 DDoS 保护造成)
      【解决方案7】:

      我也遇到过类似的问题,但原因似乎不同,这里是异常跟踪:

      java.io.FileNotFoundException: http://myhost1:8081/test/api?wait=1
          at sun.reflect.GeneratedConstructorAccessor2.newInstance(Unknown Source)
          at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
          at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
          at sun.net.www.protocol.http.HttpURLConnection$6.run(HttpURLConnection.java:1491)
          at java.security.AccessController.doPrivileged(Native Method)
          at sun.net.www.protocol.http.HttpURLConnection.getChainedException(HttpURLConnection.java:1485)
          at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1139)
          at com.doitnext.loadmonger.HttpExecution.getBody(HttpExecution.java:85)
          at com.doitnext.loadmonger.HttpExecution.execute(HttpExecution.java:214)
          at com.doitnext.loadmonger.ClientWorker.run(ClientWorker.java:126)
          at java.lang.Thread.run(Thread.java:680)
      Caused by: java.io.FileNotFoundException: http://myhost1:8081/test/api?wait=1
          at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1434)
          at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379)
          at com.doitnext.loadmonger.HttpExecution.execute(HttpExecution.java:166)
          ... 2 more
      

      所以看起来只是获取响应代码会导致 URL 连接调用 GetInputStream。

      【讨论】:

      • 我通过抛弃 HttpUrlConnection 并改用 Apache HttpClient 解决了这个问题。更好的性能和更简洁的代码。
      【解决方案8】:

      我知道这是一个旧帖子,但只是注意到这个帖子上有些东西,所以我想我会把它放在那里。

      正如杰西卡所说,使用非标准端口时会引发此异常。

      这似乎只在使用 DNS 时发生。如果我使用 IP 号,我可以指定端口号,一切正常。

      【讨论】:

        猜你喜欢
        • 2015-06-21
        • 1970-01-01
        • 1970-01-01
        • 2020-10-05
        • 2018-09-09
        • 2011-10-01
        • 2013-06-01
        • 2019-01-31
        • 2019-02-20
        相关资源
        最近更新 更多