Java 非标准 HTTP 端口源的 URLConnection FileNotFoundException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/941628/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
URLConnection FileNotFoundException for non-standard HTTP port sources
提问by jeffl8n
I was trying to use the Apache Ant Get
taskto 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.
我试图使用 Apache AntGet
任务来获取我们公司另一个团队生成的 WSDL 列表。他们将它们托管在http://....com:7925/services/上的 weblogic 9.x 服务器上。我可以通过浏览器访问该页面,但是在尝试将页面复制到本地文件进行解析时,get 任务给了我一个 FileNotFoundException。我仍然能够(使用 ant 任务)获得一个没有非标准 HTTP 端口 80 的 URL。
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.
我查看了 Ant 源代码,并将错误范围缩小到 URLConnection。似乎 URLConnection 无法识别数据是 HTTP 流量,因为它不在标准端口上,即使协议被指定为 HTTP。我使用 WireShark 嗅探了流量,页面通过网络正确加载,但仍然收到 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();
这是一个示例,您将在其中看到错误(更改 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());
}
}
}
采纳答案by objects
check the response code being returned by the server
检查服务器返回的响应代码
回答by Daniel Martin
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.
我已经在本地尝试过 - 使用提供的代码 -FileNotFoundException
除非服务器返回状态 404 响应,否则我没有得到。
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)
您确定要连接到要连接的网络服务器吗?您是否有机会连接到不同的网络服务器?(我注意到代码中的端口号与链接中的端口号不匹配)
回答by Jessica
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.
我在浏览器中接收到页面正常,但是当我尝试通过 HttpURLConnection 访问它时收到了 404。我试图访问的 URL 包含一个端口号。当我在没有端口号的情况下尝试时,我通过 HttpURLConnection 成功获得了一个虚拟页面。所以看起来非标准端口是问题所在。
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.
我开始认为访问受到限制,从某种意义上说确实如此。我的解决方案是我需要告诉服务器 User-Agent 并且我还指定了我期望的文件类型。我正在尝试读取 .json 文件,因此我认为文件类型也可能是必要的规范。
I added these lines and it finally worked:
我添加了这些行,它终于奏效了:
httpConnection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
httpConnection.setRequestProperty("Accept","*/*");
回答by bcody
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().
对我的 HTTP 请求的响应返回了状态代码 404,当我调用 getInputStream() 时导致 FileNotFoundException。我仍然想读取响应正文,所以我不得不使用不同的方法: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();
}
}
}
回答by NullPointer
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.
我试图从端口 8080 上的 J2EE servlet 以 json 格式提取数据,但收到文件未找到错误。我能够从运行在端口 80 上的 php 服务器中提取相同的 json 数据。
It turns out that in the servlet, I needed to change doGet to doPost.
事实证明,在 servlet 中,我需要将 doGet 更改为 doPost。
Hope this helps somebody.
希望这可以帮助某人。
回答by Steve Owens
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.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 连接调用GetInputStream。
回答by Zyga
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.
虽然它似乎只在使用 DNS 时发生。如果我使用 IP 号,我可以指定端口号,一切正常。
回答by serv-inc
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(); }
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(); }