FileNotFoundException从HttpURLConnection获取InputStream对象

我想发送一个URL使用HttpURLConnection(在Java中使用cUrl)发送请求。 请求的内容是xml,在结束点,应用程序处理xml并将logging存储到数据库,然后以xmlstring的forms发回响应。 该应用程序在本地托pipe在apache-tomcat上。

当我从terminal执行这个代码时,一行被按预期添加到数据库。 但从连接中获取InputStream时会引发exception

java.io.FileNotFoundException: http://localhost:8080/myapp/service/generate at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1401) at org.kodeplay.helloworld.HttpCurl.main(HttpCurl.java:30) 

这是代码

 public class HttpCurl { public static void main(String [] args) { HttpURLConnection con; try { con = (HttpURLConnection) new URL("http://localhost:8080/myapp/service/generate").openConnection(); con.setRequestMethod("POST"); con.setDoOutput(true); con.setDoInput(true); File xmlFile = new File("test.xml"); String xml = ReadWriteTextFile.getContents(xmlFile); con.getOutputStream().write(xml.getBytes("UTF-8")); InputStream response = con.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(response)); for (String line ; (line = reader.readLine()) != null;) { System.out.println(line); } reader.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } 

它令人迷惑,因为exception被追溯到InputStream response = con.getInputStream(); 而且似乎没有涉及FileNotFoundException的任何文件。

当我尝试直接打开到xml文件的连接时,它不会抛出此exception。

服务应用程序使用spring框架和Jaxb2Marshaller来创build响应xml。

ReadWriteTextFile类是从这里获取的

谢谢。

编辑:它将数据保存在数据库中,并同时发回一个404响应状态码。

我也尝试使用PHP做一个curl,并打印出CURLINFO_HTTP_CODE ,结果是200。

关于如何去debugging这个任何想法? 服务和客户端都在本地服务器上。

解决:我可以在提及SO本身的答案后解决问题。

看起来HttpURLConnection在连接到一个非标准端口的url时总是返回404响应。

添加这些线解决了它

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

我不知道你的Spring / JAXB组合,但是平均REST web服务不会在POST / PUT上返回响应主体,只是响应状态 。 你想确定它,而不是身体。

更换

 InputStream response = con.getInputStream(); 

通过

 int status = con.getResponseCode(); 

HTTP规范中提供了所有可用的状态码及其含义,如前链接。 Web服务本身也应该附带一些概述Web服务支持的所有状态代码及其特殊含义的文档(如果有的话)。

如果状态以4nn5nn ,那么您想使用getErrorStream()来读取可能包含错误细节的响应主体。

 InputStream error = con.getErrorStream(); 

FileNotFound只是一个不幸的例外,用于表示Web服务器返回了404。

对于将来有这个问题的人,原因是状态码是404(或者在我的情况下是500)。 当状态码不是200时, InpuStream函数会出现错误。

在我的情况下,我控制我自己的服务器,并返回一个500状态代码,以指示发生错误。 尽pipe我也发送了一个string消息详细的错误的身体,inputinputstream抛出一个错误,无论身体是否完全可读。

如果你控制你的服务器,我想这可以通过发送一个200状态码来处理,然后处理任何string错误响应。

在这种情况下FileNotFound意味着你从你的服务器得到了一个404 – 可能是服务器不喜欢“POST”请求?

对于其他人绊倒这一点,在尝试将SOAP请求头发送到SOAP服务时,也发生了同样的情况。 这个问题在代码中是错误的,我在发送XML主体之前先要求inputstream。 在下面的代码中, InputStream in = conn.getInputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream(); 这是事情的不正确的顺序。

 ByteArrayOutputStream out = new ByteArrayOutputStream(); // send SOAP request as part of HTTP body byte[] data = request.getHttpBody().getBytes("UTF-8"); conn.getOutputStream().write(data); if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) { Log.d(TAG, "http response code is " + conn.getResponseCode()); return null; } InputStream in = conn.getInputStream(); 

在这种情况下, FileNotFound是编码HTTP响应代码400的一种不幸的方式。

解决scheme:
只需更改本地主机IP为您的电脑
如果你想知道这个: Windows + r> cmd> ipconfig
例如:http:// 192.168.0.107 /directory/service/program.php?action=sendSomething
只需将192.168.0.107replace为您自己的IP(不要尝试127.0.0.1,因为它与本地主机相同)

请更换

 con = (HttpURLConnection) new URL("http://localhost:8080/myapp/service/generate").openConnection(); 

 con = (HttpURLConnection) new URL("http://YOUR_IP:8080/myapp/service/generate").openConnection();