URLConnection FileNotFoundException用于非标准HTTP端口源

时间:2009-06-02 20:08:46

标签: java ant urlconnection

我试图使用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());
        }
    }

}

8 个答案:

答案 0 :(得分: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();
        }
    }
}

答案 1 :(得分:19)

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

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

我开始认为访问受到限制,从某种意义上说它是。我的解决方案是我需要告诉服务器User-Agent,我还指定了我期望的文件类型。我正在尝试读取.json文件,所以我认为文件类型也可能是必要的规范。

我添加了这些行,它最终起作用了:

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

答案 2 :(得分:7)

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

答案 3 :(得分:2)

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

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

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

希望这有助于某人。

答案 4 :(得分:0)

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

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

答案 5 :(得分: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连接到callGetInputStream。

答案 6 :(得分:0)

我知道这是一个老线程,但只是注意到了这个问题,我想我会把它放在那里。

与Jessica提到的一样,当使用非标准端口时会抛出此异常。

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

答案 7 :(得分:0)

您可以使用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();
}