program story

HttpURLConnection에서 InputStream 개체를 가져 오는 동안 FileNotFoundException이 발생했습니다.

inputbox 2020. 8. 28. 07:25
반응형

HttpURLConnection에서 InputStream 개체를 가져 오는 동안 FileNotFoundException이 발생했습니다.


HttpURLConnection을 사용하여 URL에 게시 요청을 보내려고합니다 (Java에서 cUrl 사용). 요청 내용은 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();
        }
    }
  }

예외가 줄로 추적되고 InputStream response = con.getInputStream();FileNotFoundException에 관련된 파일이없는 것처럼 보이기 때문에 혼란 스럽습니다 .

xml 파일에 대한 연결을 직접 열려고하면이 예외가 발생하지 않습니다.

서비스 앱은 스프링 프레임 워크와 Jaxb2Marshaller를 사용하여 응답 xml을 생성합니다.

ReadWriteTextFile 클래스는 여기 에서 가져옵니다 .

감사.

편집 : DB에 데이터를 저장하고 동시에 404 응답 상태 코드를 보냅니다.

나는 또한 PHP를 사용하여 컬을 시도하고 CURLINFO_HTTP_CODE200으로 판명 된 것을 인쇄했습니다 .

이것을 디버깅하는 방법에 대한 아이디어가 있습니까? 서비스와 클라이언트는 모두 로컬 서버에 있습니다.

해결 : SO 자체에 대한 답변참조하여 문제를 해결할 수 있습니다.

표준 포트가 아닌 URL에 연결할 때 HttpURLConnection이 항상 404 응답을 반환하는 것 같습니다.

이 줄을 추가하면 해결되었습니다.

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. 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. 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.

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

FileNotFound is just an unfortunate exception used to indicate that the web server returned a 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). It appears the InpuStream function will throw an error when the status code is not 200.

In my case I control my own server and was returning a 500 status code to indicate an error occurred. 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.

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.


For anybody else stumbling over this, the same happened to me while trying to send a SOAP request header to a SOAP service. The issue was a wrong order in the code, I requested the input stream first before sending the XML body. In the code snipped below, the line InputStream in = conn.getInputStream(); came immediately after 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 in this case means you got a 404 from your server - could it be that the server does not like "POST" requests?


The solution:
just change localhost for the IP of your PC
if you want to know this: Windows+r > cmd > ipconfig
example: 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)


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

참고URL : https://stackoverflow.com/questions/5379247/filenotfoundexception-while-getting-the-inputstream-object-from-httpurlconnectio

반응형