HttpUrlConnection の概要
ストリームを用いた汎用の Network I/O のためのインタフェースとして、URLConnection
があり、このうち HTTP に基づいたものがHttpUrlConnection
です。さらにこの子クラスとして、HttpsUrlConnection
もあります。
Input
URLConnection#getInputStream()
で得られるInputStream
を読み取ることで、レスポンスのデータを取得します。
Output
URLConnection#getOutputStream()
で得られるOutputStream
にデータを書き出すことで、リクエストを作成します。
OutputStream
をclose()
するまでリクエストは送られません。
Error
サーバから、4xxや5xxなどのエラーレスポンスが返されると、FileNotFoundException
がスローされます(コードはここのL176)。
ただし、URLConnection
のインタフェースのほとんどはIOException
をスローすることがドキュメントに明示されているのみで、IDE のコード補完にまかせてコードを書くと、IOException
をキャッチするブロックに全てが吸収されてしまいます。
FileNotFoundException
をキャッチした場合で、サーバがエラーレスポンスに何らかのデータをくっつけて来た場合、HttpUrlConnection#getErrorStream()
でInputStream
を取得し、エラーレスポンスを読み取ります。
よって、愚直に書くと以下の様な悲しいコードになります。
InputStream in = null;
try {
in = connection.getInputStream();
// ...
} catch (FileNotFoundException e) { // IOException をキャッチするより先に FileNotFoundException をキャッチしないと IOException のキャッチブロックに行くのでこうする
System.err.println(e);
InputStream err = null;
try {
err = connection.getErrorStream();
// 4xx または 5xx なレスポンスのボディーを読み取る
// ...
} catch (IOException e) {
System.err.println(e);
} finally {
if (err != null) {
try {
err.close();
} catch (IOException e) {
System.err.println(e);
}
}
}
} catch (IOException e) {
System.err.println(e);
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
System.err.println(e);
}
}
if (connection != null) {
connection.disconnect();
}
}