URLConnection FileNotFoundException用于非标准HTTP端口源

我试图使用Apache Ant Get任务来获取我们公司中另一个团队生成的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()); } } } 

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

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

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

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

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

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

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

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

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

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

希望这有助于某人。

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

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

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

 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。

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

就像Je​​ssica提到的那样,当使用非标准端口时抛出此exception。

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

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