web-dev-qa-db-ja.com

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は here から取得されます

ありがとう。

Edit:データをDBに保存し、同時に404応答ステータスコードを送り返します。

また、phpを使用してcurlを実行し、CURLINFO_HTTP_CODEを出力してみましたが、200になりました。

これをデバッグするにはどうすればよいですか?サービスとクライアントの両方がローカルサーバー上にあります。

解決済み:SO自体で answer を参照した後、問題を解決できました。

非標準ポートでURLに接続すると、HttpURLConnectionは常に404応答を返すようです。

これらの行を追加すると解決しました

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

Spring/JAXBの組み合わせについては知りませんが、平均REST WebサービスはPOST/PUTで応答本文を返さず、単に response status を返します。あなたは体の代わりにそれを決定したいです。

交換

InputStream response = con.getInputStream();

沿って

int status = con.getResponseCode();

使用可能なすべてのステータスコードとその意味は、前にリンクしたとおり、HTTP仕様で使用できます。 Webサービス自体には、Webサービスでサポートされるすべてのステータスコードとその特別な意味(存在する場合)の概要を示すドキュメントも付属する必要があります。

ステータスが4nnまたは5nnで始まる場合、代わりにgetErrorStream()を使用して、エラーの詳細が含まれている可能性のある応答本文を読み取ります。

InputStream error = con.getErrorStream();
122
BalusC

FileNotFoundは、Webサーバーが404を返したことを示すために使用される不幸な例外です。

47
Jon Skeet

将来この問題を抱える人にとって、理由はステータスコードが404(または私の場合は500)だったからです。ステータスコードが200でない場合、InpuStream関数はエラーをスローするようです。

私の場合、自分のサーバーを制御し、エラーが発生したことを示す500ステータスコードを返していました。エラーの詳細を示す文字列メッセージを含む本文も送信しましたが、inputstreamは、本文が完全に読み取り可能であってもエラーをスローしました。

サーバーを制御している場合、200ステータスコードを自分で送信し、文字列エラーレスポンスが何であれ処理することで処理できると思います。

28
Terence Chow

これにつまずいた人は、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をエンコードする残念な方法でした。

5
zero0cool

この場合のFileNotFoundは、サーバーから404を取得したことを意味します。サーバーが「POST」リクエストを好まない可能性がありますか?

4
tofarr

解決策:
変更localhostIPあなたのPC
これを知りたい場合:Windows + r> cmd> ipconfig
例:http://192.168.0.107/directory/service/program.php?action=sendSomething
自分のIPに192.168.0.107を置き換える(127.0.0.1localhost)と同じため

0
charlie