简体   繁体   English

URLConnection FileNotFoundException用于非标准HTTP端口源

[英]URLConnection FileNotFoundException for non-standard HTTP port sources

I was trying to use the Apache Ant Get task to get a list of WSDLs generated by another team in our company. 我试图使用Apache Ant Get任务来获取我们公司中另一个团队生成的WSDL列表。 They have them hosted on a weblogic 9.x server on http://....com:7925/services/ . 他们将它们托管在http://.... com:7925 / services /上的weblogic 9.x服务器上。 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. 我能够通过浏览器访问该页面,但是当尝试将页面复制到本地文件进行解析时,get任务会给我一个FileNotFoundException。 I was still able to get (using the ant task) a URL without the non-standard port 80 for HTTP. 我仍然能够(使用ant任务)获得没有HTTP的非标准端口80的URL。

I looked through the Ant source code, and narrowed the error down to the URLConnection. 我查看了Ant源代码,并将错误缩小到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. 似乎URLConnection无法识别数据是HTTP流量,因为它不在标准端口上,即使协议被指定为HTTP。 I sniffed the traffic using WireShark and the page loads correctly across the wire, but still gets the FileNotFoundException. 我使用WireShark嗅探了流量,并且页面正确地加载了网页,但仍然得到了FileNotFoundException。

Here's an example where you will see the error (with the URL changed to protect the innocent). 这是一个示例,您将看到错误(更改URL以保护无辜者)。 The error is thrown on connection.getInputStream(); 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());
        }
    }

}

The response to my HTTP request returned with a status code 404, which resulted in a FileNotFoundException when I called getInputStream(). 我的HTTP请求响应返回状态代码404,当我调用getInputStream()时导致FileNotFoundException。 I still wanted to read the response body, so I had to use a different method: HttpURLConnection#getErrorStream() . 我仍然想读取响应体,所以我不得不使用不同的方法: HttpURLConnection#getErrorStream()

Here's a JavaDoc snippet of getErrorStream(): 这是getErrorStream()的JavaDoc片段:

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. 典型示例是当HTTP服务器以404响应时,这将导致在连接中抛出FileNotFoundException,但服务器发送了一个HTML帮助页面,其中包含有关如何操作的建议。

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

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. 我在浏览器中收到的页面很好,但是当我尝试通过HttpURLConnection访问它时得到了404。 The URL I was trying to access contained a port number. 我尝试访问的URL包含一个端口号。 When I tried it without the port number I successfully got a dummy page through the HttpURLConnection. 当我尝试没有端口号时,我通过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. 我的解决方案是我需要告诉服务器User-Agent,我还指定了我期望的文件类型。 I am trying to read a .json file, so I thought the file type might be a necessary specification as well. 我正在尝试读取.json文件,所以我认为文件类型也可能是必要的规范。

I added these lines and it finally worked: 我添加了这些行,它最终起作用:

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

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

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. 我试图从端口8080上的J2EE servlet中以json格式提取数据,但是收到了文件未找到错误。 I was able to pull this same json data from a php server running on port 80. 我能够从端口80上运行的php服务器中提取相同的json数据。

It turns out that in the servlet, I needed to change doGet to doPost. 事实证明,在servlet中,我需要将doGet更改为doPost。

Hope this helps somebody. 希望这有助于某人。

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. 所以看起来只是获取响应代码会导致URL连接到callGetInputStream。

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. 像Jessica提到的那样,当使用非标准端口时抛出此异常。

It only seems to happen when using DNS though. 它似乎只在使用DNS时发生。 If I use IP number I can specify the port number and everything works fine. 如果我使用IP号码,我可以指定端口号,一切正常。

You could use OkHttp : 你可以使用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(); } 

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. 我在本地尝试过 - 使用提供的代码 - 除了服务器返回状态404响应之外,我没有得到FileNotFoundException

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) (我注意到代码中的端口号与链接中的端口号不匹配)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM