私のJavaサーブレットでは、エラーを示すHTTPステータスコードを返したい場合があり、返されたステータスコードに基づいてクライアントが応答を読み取って処理できるようにしたい場合があります。たとえば、私のアプリケーションは、Google AppEngineJavaランタイムのチャネルAPIを扱います。要求しているクライアントIDがまだチャネルのトークンを要求していない場合、サーブレットは403ステータスコードを返し、クライアントはそれに応じて応答を処理します(サーブレットからすぐにトークンを要求します)。
ただし、クライアントがHttpURLConnectionを使用してHTTP応答を読み取る場合。入力ストリームから応答を読み取ることができる代わりに、この素敵なスタックトレースがスローされます。
java.io.IOException: Server returned HTTP response code: 403 for URL: http://localhost:8083/rest/fb/echo
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
at sun.net.www.protocol.http.HttpURLConnection$6.run(HttpURLConnection.java:1458)
at java.security.AccessController.doPrivileged(Native Method)
at sun.net.www.protocol.http.HttpURLConnection.getChainedException(HttpURLConnection.java:1452)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1106)
...
Caused by: java.io.IOException: Server returned HTTP response code: 403 for URL: http://localhost:8083/rest/fb/echo
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1403)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:397)
この投稿を書いているときに、接続から失敗を意味するステータスコードを読み取った場合、接続の入力ストリームから読み取るべきではないのではないかと思い始めました。とにかく、私は他の人がこれについてどう思うか聞いてみたいです。
ノート
私のサーブレットはSitebricksを使用して、リッスンするRESTエンドポイントをメソッドに提供します。また、Sitebricksを使用すると、次のように応答とステータスコードを送信できます。
MyObject response = ...;
int statusCode = ...;
...
return Reply.with(response).as(Json.class).type("application/json").status(statusCode);