How to handle session timeout exceptions in Spring MVC


Codever Logo

(P) Codever is an open source bookmarks and snippets manager for developers & co. See our How To guides to help you get started. Public bookmarks repos on Github ⭐🙏


The challenge

I have been getting complaints from people who were trying to suggest a podcast to Podcastpedia.org, and that for a good reason. They were getting a page with the following message:

"Unknown error. Please inform us about it with the Error indication form."

This is the default page rendered when an unknown exception occurs. Although this is prettier than displaying the error stacktrace, it should be avoided – it didn’t tell the visitors much and me neither.

Octocat Source code for this post is available on Github - podcastpedia.org is an open source project.

I have been struggling with this for some time and couldn’t find the reason, because everytime I would fill the form with the same input provided by the visitors it would work perfectly for me. Until today, when somehow the session expiration setting popped into my mind. I recalled setting the session timeout pretty short – 1 minute (default in Tomcat is 30 minutes) – in the web.xml file, for “performance” reasons:

<!-- set session timeout for 1 minute <url-pattern>/*.atom</url-pattern> -->
<session-config>
	<session-timeout>1</session-timeout>
	<tracking-mode>COOKIE</tracking-mode>
</session-config>

I have to admit one minute is extremly short. So I filled the form, waited 1 min and 13 seconds et voilà, I got the same error when trying to submit.

The Spring controller handling the podcast submission form uses the @SessionAttributes("addPodcastForm") annotation. This indicates the model object – addPodcastForm – to be held in a session, so that if a validation error ocurs, the visitor doesn’t have to fill the fields all over again. This annotation forces the existence of a valid session and triggered the error message.

The solution

Modify session-timeout in web.xml

So the actual fix for this challenge was pretty easy, I’ve just increased the session-timeout value from 1 to 10 minutes. But what if a visitor starts filling the form, goes away, drinks a coffee and returns to submit the form after 15 minutes, I wouldn’t want her to see the same "Unknown error..." message – one pointing to the error cause and how the user might react would be much better.

Meet the @ExceptionHandler

Well, Spring isn’t considered a mighty framework for nothing. To catch such an exception all I had to do is annotate a method in the controller, which handles the form submission requests, with @ExceptionHandler and specify which type of Exception to handle:

@ExceptionHandler(HttpSessionRequiredException.class)
@ResponseStatus(value = HttpStatus.UNAUTHORIZED, reason="The session has expired"))
public String handleSessionExpired(){
  return "sessionExpired";
}

The HttpSessionRequiredException requires a pre-existing session. The @ResponseStatus is optional and marks the method with the status code and the reason that should be returned. Several return types are supported for handler methods, but when I return a String – sessionExpired – this value is interpreted as a view name. In the Tiles configuration there is a definition which, based on this name, renders now a page with a corresponding message for session expiration.

Note: Please see my post Spring MVC and Apache Tiles integration example for an explanation of using Tiles definitions with Spring MVC.

Exception handling configuration in the application context

............
<bean class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver" p:order="1" />
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" p:order="2" p:defaultErrorView="uncaughtException">
  <property name="exceptionMappings">
	<props>
	  <prop key="org.springframework.core.NestedRuntimeException.DataAccessException">dataAccessFailure</prop>
	  <prop key="org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException">resourceNotFound</prop>
	  <prop key="org.springframework.beans.TypeMismatchException">resourceNotFound</prop>
	  <prop key="org.springframework.web.bind.MissingServletRequestParameterException">resourceNotFound</prop>
	</props>
  </property>
</bean>
............

The exception handling is configured in the application context via

  • ExceptionHandler – resolves exceptions through @ExceptionHandler methods as our above method. It is configured to take precedence because the p:order to 1.
  • SimpleMappingExceptionResolver – allows for mapping exception class names to view names, either for a set of given handlers or for all handlers in the DispatcherServlet. Notice here the defaultErrorView attribute which sets the name of the default error view, if no specific mapping was found – this was the case for the session timeout exception.
  • Well, that’s it. I hope you could learn something from this as I did.

    Octocat Source code for this post is available on Github - podcastpedia.org is an open source project.

    Resources

    1. Spring framework reference – MVC Handling exceptions
    Podcastpedia image

    Adrian Matei

    Creator of Podcastpedia.org and Codepedia.org, computer science engineer, husband, father, curious and passionate about science, computers, software, education, economics, social equity, philosophy - but these are just outside labels and not that important, deep inside we are all just consciousness, right?
    Subscribe to our newsletter for more code resources and news

    Adrian Matei (aka adixchen)

    Adrian Matei (aka adixchen)
    Life force expressing itself as a coding capable human being

    routerLink with query params in Angular html template

    routerLink with query params in Angular html template code snippet Continue reading