当从 HttpURLConnection 获取 InputStream 对象时发生 FileNotFoundException

我正在尝试使用 HttpURLConnection (用于在 java 中使用 cUrl)向 URL 发送一个帖子请求。 请求的内容是 xml,在终点,应用程序处理 xml 并将记录存储到数据库中,然后以 xml 字符串的形式发回响应。这个应用程序本地托管在 apache-tomcat 上。

当我从终端执行此代码时,一行将按预期添加到 db。但是当从连接获取 InputStream 时,会抛出如下异常

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

Its confusing because the exception is traced to the line InputStream response = con.getInputStream(); and there doesn't seem to be any file involved for a FileNotFoundException.

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

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

ReadWriteTextFile 类取自 给你

谢谢。

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

我还试着用 php 做一个旋度,然后打印出 CURLINFO_HTTP_CODE,结果是200。

Any ideas on how do I go about debugging this ? Both service and client are on the local server.

决心: 我可以在参考了 SO 本身的 回答之后解决这个问题。

当用非标准端口连接到 URL 时,HttpURLConnection 似乎总是返回404响应。

加上这些线就解决了

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

在这种情况下,FileNotFind 意味着您从服务器获得了一个404-服务器是否不喜欢“ POST”请求?

FileNotFound is just an unfortunate exception used to indicate that the web server returned a 404.

我不知道您的 Spring/JAXB 组合,但是一般的 REST webservice 不会在 POST/PUT 上返回响应主体,只返回 回应状态。你想要确定它,而不是尸体。

替换

InputStream response = con.getInputStream();

作者

int status = con.getResponseCode();

所有可用的状态代码及其含义都可以在 HTTP 规范中找到,如前所述。Webservice 本身也应该附带一些文档,概述 Webservice 支持的所有状态代码及其特殊含义(如果有的话)。

If the status starts with 4nn or 5nn, you'd like to use getErrorStream() instead to read the response body which may contain the error details.

InputStream error = con.getErrorStream();

对于其他在这个问题上遇到困难的人来说,同样的事情也发生在我身上,当我试图将 SOAP 请求头发送到 SOAP 服务时。问题是代码顺序错误,我在发送 XML 主体之前首先请求了输入流。在下面剪切的代码中,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的一种不幸的方式。

对于将来有此问题的任何人,原因是状态代码是404(在我的例子中是500)。当状态码不是200时,似乎 InpuStream函数将抛出一个错误。

在我的情况下,我控制我自己的服务器,并返回一个500状态码,以表明发生了一个错误。尽管我也发送了一个包含详细说明错误的字符串消息的主体,但是 inputstream抛出了一个错误,而不管主体是否完全可读。

如果您控制您的服务器,我想这可以通过发送自己200状态码,然后处理任何字符串错误响应来处理。

请换衣服

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

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

The solution:
只要改变你的电脑的 IP本地主机
如果你想知道这个: Windows + r > cmd > ipconfig
例如: http://abc0/directory/service/program.php?action=sendsomething
只需替换 192.168.0.107为您自己的 IP (不要尝试 127.0.0.1,因为它与 localhost相同)

在本例中,FileNotfound 意味着您从服务器获得了一个404

必须设置请求内容类型标头参数 将“ content-type”请求头设置为“ application/JSON”,以 JSON 格式发送请求内容。

必须设置此参数以便以 JSON 格式发送请求正文。

如果不这样做,服务器将返回 HTTP状态码“400-bad request”。

con.setRequestProperty("Content-Type", "application/json; utf-8");

完整脚本->

public class SendDeviceDetails extends AsyncTask<String, Void, String> {


@Override
protected String doInBackground(String... params) {


String data = "";
String url = "";


HttpURLConnection con = null;
try {


// From the above URL object,
// we can invoke the openConnection method to get the HttpURLConnection object.
// We can't instantiate HttpURLConnection directly, as it's an abstract class:
con = (HttpURLConnection)new URL(url).openConnection();
//To send a POST request, we'll have to set the request method property to POST:
con.setRequestMethod("POST");


// Set the Request Content-Type Header Parameter
// Set “content-type” request header to “application/json” to send the request content in JSON form.
// This parameter has to be set to send the request body in JSON format.
//Failing to do so, the server returns HTTP status code “400-bad request”.
con.setRequestProperty("Content-Type", "application/json; utf-8");
//Set Response Format Type
//Set the “Accept” request header to “application/json” to read the response in the desired format:
con.setRequestProperty("Accept", "application/json");


//To send request content, let's enable the URLConnection object's doOutput property to true.
//Otherwise, we'll not be able to write content to the connection output stream:
con.setDoOutput(true);


//JSON String need to be constructed for the specific resource.
//We may construct complex JSON using any third-party JSON libraries such as jackson or org.json
String jsonInputString = params[0];


try(OutputStream os = con.getOutputStream()){
byte[] input = jsonInputString.getBytes("utf-8");
os.write(input, 0, input.length);
}


int code = con.getResponseCode();
System.out.println(code);


//Get the input stream to read the response content.
// Remember to use try-with-resources to close the response stream automatically.
try(BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"))){
StringBuilder response = new StringBuilder();
String responseLine = null;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
System.out.println(response.toString());
}


} catch (Exception e) {
e.printStackTrace();
} finally {
if (con != null) {
con.disconnect();
}
}


return data;
}


@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.e("TAG", result); // this is expecting a response code to be sent from your server upon receiving the POST data
}

宣布死亡

new SendDeviceDetails().execute("");

您可以在本教程中找到更多详细信息

https://www.baeldung.com/httpurlconnection-post