Monday 18 May 2015

Miniature post: calling super in HttpServlet methods

Introduction

Lately I was writing some servlets for the Octopus SSO modules which I'm developing right now. Not used to do this anymore, I made a silly mistake which took quit some time to find out what I did wrong.

Servlets

Although they are still the basis of all web frameworks today, we don't write them that much anymore (at least, I don't do it)

So, I needed to have a simple servlet which performs some actions when it is called through the GET method.  Something like this (some code left out, see further on)


@WebServlet(urlPatterns = "/octopusSSOCallback")
public class SSOCallbackServlet extends HttpServlet {
   @Override
   protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
      // Some things to keep track of the user
      SavedRequest savedRequest = WebUtils.getAndClearSavedRequest(httpServletRequest);
      httpServletResponse.sendRedirect(savedRequest != null ? savedRequest.getRequestUrl() : getRootUrl(httpServletRequest));
   }

}

When I did some tests, I got the following exception in the log.

java.lang.IllegalStateException: UT010019: Response already committed

So, the redirect couldn't be performed because something else closed the response and informed the browser what to do.

So I tried all obvious things what I possibly could have done wrong.  And I started removing code parts in the area marked with the comment // Some things to ...  to find what caused the behaviour.

But nothing solved the issue.

The next thing I tried was to remove the redirect itself, because that was the statement which gave me the exception. And I replaced it with some hello world message stuff.

The exception was gone, of course, but now I received an Http Status 405: method not allowed.

But how could the method not be allowed as I have written some code for it and verified that it gets executed by debugging the code? I was totally lost and didn't have any clue what was going on. I even thought for a moment that the application server had a bug. But that was absurd because I wrote some other servlets a few months ago on the same server.

And then some question on a forum lead me to the solution.

As a good practice, and because the IDE generated me the code as such, I always call the super method when I do override a method.  That is mostly the idea when you override some method.  Do the standard thing and then something additional you want.

So my code contained the following statement as the first line:

super.doGet(httpServletRequest, httpServletResponse);

And the default functionality of the servlet methods is to answer with a Http status 405.

Conclusion

You should always verify what the default functionality of a method is, also when it is defined in your coding standards that you should call the super method. :)