非标准 HTTP 端口源的 URLConnection FileNotFoundException

发布于 2024-07-22 09:20:04 字数 1307 浏览 8 评论 0原文

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

我查看了 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());
        }
    }

}

I was trying to use the Apache Ant Get task to get a list of WSDLs generated by another team in our company. They have them hosted on a weblogic 9.x server on http://....com:7925/services/. I am able to get to the page through a browser, but the get task gives me a FileNotFoundException when trying to copy the page to a local file to parse. I was still able to get (using the ant task) a URL without the non-standard port 80 for HTTP.

I looked through the Ant source code, and narrowed the error down to the URLConnection. It seems as though the URLConnection doesn't recognize the data is HTTP traffic, since it isn't on the standard port, even though the protocol is specified as HTTP. I sniffed the traffic using WireShark and the page loads correctly across the wire, but still gets the FileNotFoundException.

Here's an example where you will see the error (with the URL changed to protect the innocent). The error is thrown on 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());
        }
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

心如狂蝶 2024-07-29 09:20:04

对我的 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();
        }
    }
}

The response to my HTTP request returned with a status code 404, which resulted in a FileNotFoundException when I called getInputStream(). I still wanted to read the response body, so I had to use a different method: HttpURLConnection#getErrorStream().

Here's a JavaDoc snippet of getErrorStream():

Returns the error stream if the
connection failed but the server sent
useful data nonetheless. The typical
example is when an HTTP server
responds with a 404, which will cause
a FileNotFoundException to be thrown
in connect, but the server sent an
HTML help page with suggestions as to
what to do.

Usage example:

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();
        }
    }
}
微暖i 2024-07-29 09:20:04

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

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

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

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

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

This is an old thread, but I had a similar problem and found a solution that is not listed here.

I was receiving the page fine in the browser, but got a 404 when I tried to access it via the HttpURLConnection. The URL I was trying to access contained a port number. When I tried it without the port number I successfully got a dummy page through the HttpURLConnection. So it seemed the non-standard port was the problem.

I started thinking the access was restricted, and in a sense it was. My solution was that I needed to tell the server the User-Agent and I also specify the file types I expect. I am trying to read a .json file, so I thought the file type might be a necessary specification as well.

I added these lines and it finally worked:

httpConnection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
httpConnection.setRequestProperty("Accept","*/*");
夏花。依旧 2024-07-29 09:20:04

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

check the response code being returned by the server

薄荷梦 2024-07-29 09:20:04

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

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

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

希望这对某人有帮助。

I know this is an old thread but I found a solution not listed anywhere here.

I was trying to pull data in json format from a J2EE servlet on port 8080 but was receiving the file not found error. I was able to pull this same json data from a php server running on port 80.

It turns out that in the servlet, I needed to change doGet to doPost.

Hope this helps somebody.

回眸一笑 2024-07-29 09:20:04

您可以使用 OkHttp

OkHttpClient 客户端 = new OkHttpClient(); 

  String run(String url) 抛出 IOException { 
    请求 request = new Request.Builder() 
        .url(网址) 
        。建造(); 

    响应response = client.newCall(request).execute(); 
    返回response.body().string(); 
  } 
  

You could use 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();
}
音盲 2024-07-29 09:20:04

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

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

I've tried that locally - using the code provided - and I don't get a FileNotFoundException except when the server returns a status 404 response.

Are you sure that you're connecting to the webserver you intend to be connecting to? Is there any chance you're connecting to a different webserver? (I note that the port number in the code doesn't match the port number in the link)

终弃我 2024-07-29 09:20:04

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

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。

I have run into a similar issue but the reason seems to be different, here is the exception trace:

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

So it would seem that just getting the response code will cause the URL connection to callGetInputStream.

素罗衫 2024-07-29 09:20:04

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

正如 Jessica 提到的,使用非标准端口时会抛出此异常。

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

I know this is an old thread but just noticed something on this one so thought I will just put it out there.

Like Jessica mentioned, this exception is thrown when using non-standard port.

It only seems to happen when using DNS though. If I use IP number I can specify the port number and everything works fine.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文