23

我试图使用 Apache AntGet任务来获取由我们公司的另一个团队生成的 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());
        }
    }

}
4

8 回答 8

46

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

这是 getErrorStream() 的 JavaDoc 片段:

如果连接失败但服务器仍然发送了有用的数据,则返回错误流。典型的例子是当 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();
        }
    }
}
于 2010-11-09T18:07:37.080 回答
20

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

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

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

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

httpConnection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
httpConnection.setRequestProperty("Accept","*/*");
于 2010-02-16T16:42:42.757 回答
8

检查服务器返回的响应代码

于 2009-06-03T03:19:51.100 回答
2

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

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

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

希望这可以帮助某人。

于 2012-10-10T12:17:41.140 回答
1

你可以使用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();
}
于 2018-07-20T15:20:15.857 回答
0

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

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

于 2009-06-03T01:58:24.463 回答
0

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

就像杰西卡提到的那样,使用非标准端口时会引发此异常。

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

于 2013-10-10T08:42:52.370 回答
0

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

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。

于 2012-11-30T00:03:37.283 回答