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