Androidアプリから外部サイトにHTTPリクエストを行い情報を取得する場合HttpURLConnectionを使うと思いますが、HttpURLConnection.getInputStreamでHTTPレスポンスを取得した時にFileNotFoundExceptionが発生することがあります。

ここでは、そのときの原因と対処法について記載します。

FileNotFoundExceptionの原因

HTTPレスポスがまだ来ていない状態でレスポンスを取得しようとHttpURLConnection.getInputStreamを実行するとFileNotFoundExceptionが発生してしまいます。

私の場合はGETリクエストを行う際にHttpURLConnection.setDoOutput(true)を指定してしまっていたことが原因でした。

setDoOutputを指定した場合は接続後にリクエストボディを送信する必要があるのですが、HTTP GETではリクエストボディが不要のため、これを送信せずにレスポンスを取得しようとしていました。

// HTTPリクエスト送信
URL url = new URL("http://xxx");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setInstanceFollowRedirects(false);
con.setDoInput(true);
con.setDoOutput(true); //これが悪かった
con.connect(); 
 
//setDoOutputがtrueの場合はリクエストボディを送信する必要がある
 
// レスポンスの取得
InputStream in = con.getInputStream(); //ここでFileNotFoundExceptionが発生
// レスポンスを処理
in.close();

setDoOutput(false)とすることで解消

というわけでHTTP GETでリクエストボディを送信しない場合は、setDoOutput(false)とすることでFileNotFoundExceptionが解消されました。(setDoOutput自体を何も指定しなくてもデフォルトはfalse)