In my Java servlet, there are instances where I want to return an HTTP status code signifying an error and I want the client to be able to read and handle the response based on the status code returned. For example, my application deals with the Channel API for the Google App Engine Java runtime. If the requesting client ID has not yet requested a token for the channel, then the servlet will return a 403 status code and the client will handle the response accordingly (request a token immediately from the servlet).
However, when the client reads the HTTP response using HttpURLConnection. Instead of being able to read the response from the input stream, I am thrown this lovely stack trace:
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)
While I was writing this post, I began to think that perhaps I should not read from the connection's input stream if I read a status code from the connection that signified a non-success. Regardless, I'd love to hear what others think about this.
NOTE
My servlet uses Sitebricks to provide my methods with a REST endpoint to listen to. Also, Sitebricks allows me to send the response and status code like so:
MyObject response = ...;
int statusCode = ...;
...
return Reply.with(response).as(Json.class).type("application/json").status(statusCode);
I do think you're right. You'll have to check status before reading from input stream.