简体   繁体   English

从 HttpURLConnection 获取 InputStream 对象时出现 FileNotFoundException

[英]FileNotFoundException while getting the InputStream object from HttpURLConnection

I am trying to send a post request to a url using HttpURLConnection (for using cUrl in java).我正在尝试使用 HttpURLConnection(用于在 java 中使用 cUrl)向 url 发送发布请求。 The content of the request is xml and at the end point, the application processes the xml and stores a record to the database and then sends back a response in form of xml string.请求的内容是 xml,在终点,应用程序处理 xml 并将记录存储到数据库,然后以 xml 字符串的形式发回响应。 The app is hosted on apache-tomcat locally.该应用程序在本地托管在 apache-tomcat 上。

When I execute this code from the terminal, a row gets added to the db as expected.当我从终端执行此代码时,一行会按预期添加到数据库中。 But an exception is thrown as follows while getting the InputStream from the connection但是从连接中获取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)

Here is the code这是代码

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();它令人困惑,因为异常被追踪到行InputStream response = con.getInputStream(); and there doesn't seem to be any file involved for a FileNotFoundException.并且似乎没有任何文件涉及 FileNotFoundException。

When I try to open a connection to an xml file directly, it doesn't throw this exception.当我尝试直接打开与 xml 文件的连接时,它不会抛出此异常。

The service app uses spring framework and Jaxb2Marshaller to create the response xml.服务应用程序使用 spring 框架和 Jaxb2Marshaller 来创建响应 xml。

The class ReadWriteTextFile is taken from here ReadWriteTextFile 类取自此处

Thanks.谢谢。

Edit: Well it saves the data in the DB and sends back a 404 response status code at the same time.编辑:它会将数据保存在数据库中,同时发回 404 响应状态代码。

I also tried doing a curl using php and print out the CURLINFO_HTTP_CODE which turns out to be 200.我还尝试使用 php 进行卷曲并打印出CURLINFO_HTTP_CODE结果是 200。

Any ideas on how do I go about debugging this?关于如何调试这个的任何想法? Both service and client are on the local server.服务和客户端都在本地服务器上。

Resolved: I could solve the problem after referring to an answer on SO itself.已解决:我可以在参考SO本身的答案后解决问题。

It seems HttpURLConnection always returns 404 response when connecting to a url with a non standard port.似乎 HttpURLConnection 在连接到具有非标准端口的 url 时总是返回 404 响应。

Adding these lines solved it添加这些行解决了它

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

I don't know about your Spring/JAXB combination, but the average REST webservice won't return a response body on POST/PUT, just a response status .我不知道你的 Spring/JAXB 组合,但一般的 REST web 服务不会在 POST/PUT 上返回响应主体,只是一个响应状态 You'd like to determine it instead of the body.你想确定它而不是身体。

Replace代替

InputStream response = con.getInputStream();

by经过

int status = con.getResponseCode();

All available status codes and their meaning are available in the HTTP spec, as linked before. HTTP 规范中提供了所有可用的状态代码及其含义,如前所述。 The webservice itself should also come along with some documentation which overviews all status codes supported by the webservice and their special meaning, if any. Web 服务本身还应该附带一些文档,这些文档概述了 Web 服务支持的所有状态代码及其特殊含义(如果有的话)。

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.如果状态以4nn5nn ,您希望改用getErrorStream()来读取可能包含错误详细信息的响应正文。

InputStream error = con.getErrorStream();

FileNotFound is just an unfortunate exception used to indicate that the web server returned a 404. FileNotFound只是一个不幸的异常,用于指示 Web 服务器返回 404。

To anyone with this problem in the future, the reason is because the status code was a 404 (or in my case was a 500).对于将来遇到此问题的任何人,原因是状态代码是 404(或者在我的情况下是 500)。 It appears the InpuStream function will throw an error when the status code is not 200.当状态代码不是 200 时, InpuStream函数似乎会抛出错误。

In my case I control my own server and was returning a 500 status code to indicate an error occurred.在我的例子中,我控制我自己的服务器并返回 500 状态代码以指示发生错误。 Despite me also sending a body with a string message detailing the error, the inputstream threw an error regardless of the body being completely readable.尽管我还发送了一个包含详细说明错误的字符串消息的正文,但无论正文是否完全可读,输入inputstream都会抛出错误。

If you control your server I suppose this can be handled by sending yourself a 200 status code and then handling whatever the string error response was.如果您控制服务器,我想这可以通过向自己发送 200 状态代码然后处理字符串错误响应来处理。

For anybody else stumbling over this, the same happened to me while trying to send a SOAP request header to a SOAP service.对于其他遇到此问题的人,在尝试将 SOAP 请求标头发送到 SOAP 服务时,同样的事情也发生在我身上。 The issue was a wrong order in the code, I requested the input stream first before sending the XML body.问题是代码中的顺序错误,我在发送 XML 正文之前先请求了输入流。 In the code snipped below, the line InputStream in = conn.getInputStream();在下面的代码中, InputStream in = conn.getInputStream();came immediately after ByteArrayOutputStream out = new ByteArrayOutputStream();ByteArrayOutputStream out = new ByteArrayOutputStream(); which is the incorrect order of things.这是错误的顺序。

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 in this case was an unfortunate way to encode HTTP response code 400.在这种情况下, FileNotFound是一种不幸的编码 HTTP 响应代码 400 的方式。

FileNotFound in this case means you got a 404 from your server - could it be that the server does not like "POST" requests?在这种情况下,FileNotFound 意味着您从服务器收到了 404 - 可能是服务器不喜欢“POST”请求吗?

FileNotFound in this case means you got a 404 from your server在这种情况下,FileNotFound 意味着您从服务器收到了 404

You Have to Set the Request Content-Type Header Parameter Set “content-type” request header to “application/json” to send the request content in JSON form.您必须设置请求内容类型标头参数 将“content-type”请求标头设置为“application/json”,以便以 JSON 形式发送请求内容。

This parameter has to be set to send the request body in JSON format.必须设置此参数才能以 JSON 格式发送请求正文。

Failing to do so, the server returns HTTP status code “400-bad request”.如果不这样做,服务器将返回 HTTP 状态代码“400-bad request”。

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

Full Script ->完整脚本 ->

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
}

and call it并称之为

new SendDeviceDetails().execute("");

you can find more details in this tutorial您可以在本教程中找到更多详细信息

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

The solution:解决方案:
just change localhost for the IP of your PC只需将localhost更改为您 PC 的IP
if you want to know this: Windows+r > cmd > ipconfig如果你想知道这个: Windows+r > cmd > ipconfig
example: http:// 192.168.0.107 /directory/service/program.php?action=sendSomething例子:http://192.168.0.107/directory/service/program.php?action= sendSomething
just replace 192.168.0.107 for your own IP (don't try 127.0.0.1 because it's same as localhost )只需将192.168.0.107替换为您自己的 IP(不要尝试127.0.0.1因为它与localhost相同)

Please change请更换

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

To

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从android中的HttpURLConnection获取InputStream时获取UnknownLengthHttpInputStream - Getting UnknownLengthHttpInputStream while getting InputStream from HttpURLConnection in android 从HttpURLConnection InputStream获取不正确的输出 - Getting improper Output from HttpURLConnection InputStream 来自HttpURLConnection的对象的InputStream无法获取所有数据 - InputStream for Objects from HttpURLConnection Not Getting All Data 如何使用httpurlconnection从InputStream读取时设置超时? - How to set a timeout while reading from InputStream using httpurlconnection? 来自HttpURLConnection的InputStream:何时断开连接? - InputStream from HttpURLConnection: When to disconnect? 为httpURLConnection获取java.io.FileNotFoundException - getting java.io.FileNotFoundException for httpURLConnection Java inputStream作为对象属性,关闭HttpURLConnection - Java inputStream as object property, close HttpURLConnection 从Google获取输入流时连接被拒绝 - Connection refused while getting inputstream from google 从HttpUrlConnection的inputstream读取速度慢 - Slow read from HttpUrlConnection's inputstream 使用 getResource() 从资源文件夹获取文件时出现 FileNotFoundException - FileNotFoundException while getting file from resources folder using getResource()
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM