Reference Data is a term used very frequently by Spring MVC developers, especially ones which use the pre-made Spring controllers. The idea of Reference Data has mainly come from the referenceData method, located in the AbstractFormController, which is a base class for both the SimpleFormController and AbstractWizardFormController. The former is a very popular and well used controller in Spring MVC applications. Reference Data is information which is added to the model for use by the view, be it jstl, pdf or freemarker. The terms Model Data and Reference Data are used interchangeably as they are the same; the former is a newer way to refer to information being added to the ‘model’ of the page (Spring 2.5 brought in the new concept of a ‘model map’, where the model is separate to the ModelAndView). This, in itself, paves a very obvious path to the new @ModelAttribute annotation which has appeared in Spring 2.5, a new way to add Reference Data (or Model information) to the ModelMap. Have I lost you?

Reference Data can be of two forms – page specific and application/site specific. Page model data could be lists of products, product categories, number of users on the site or simply data to go into lists and combo boxes, for example. Application/site specific model data is usually simpler and narrower in scope, for example, css and image locations.

This post is going to focus on site / application reference data. I don’t want to delve into too much of the already known (2.0 reference data), instead I would like to focus on the @ModelAttribute annotation and using Interceptors for adding this data to your ModelMap / ModelAndView.

1. model attribute on every set of reference data

The first example is the simplest but not the cleanest; simply put we are going to add the page specific data using individual @ModelAttribute annotated methods.

This is better than the first example as we have now grouped common behaviour into a super class. This approach is good for a couple of pieces of reference data, but not for many as it becomes a bit messy.

3. model attribute on one method for large common set of reference data, all in a super class

Okay, so as the title says, we are going to use the helpful autowiring magic Spring MVC weaves and have only one method for the model data.

But all the previous examples have a common issue, as all @ModelAttribute methods are run before the handler is executed, if the handler returns a redirect the model data will be added to the url as a query string. This should be avoided at all costs as it could expose some secrets on how you have put together your application. One example I propose, which came out of a forum post I helped answer (read more here), is to create a HandlerInterceptor, which implements the postHandle method and add the model data here. Let’s take a look.

4. HandlerInterceptor for common reference data within the entire web application

(also, just a quick sorry for the crap formatting of the code below, WordPress doesn’t handle code very well)

I like this approach the most as it abstracts the common reference data out of the controllers and is only applied on views which are not redirects; this could be further improved to only work with certain views only (like jstl, freemarker etc.). This set-up does have one major flaw – postHandle methods on HandlerInterceptors are not called when Exceptions occur during handler processing. This means that if you use the SimpleMappingExceptionResolver then you will need to extend it and possibly inject the interceptor in and call the addCommonModelData method. Otherwise you could look at abstracting the addCommonModelData out of the HandlerInterceptor, put it in its own class, declare it as a bean, and inject it into the HandlerInterceptor and HandlerExceptionResolver. Also to note, a small downside to this approach is that you need to register the HandlerInterceptor with any mappers you use, if it be bean name, simple mapping, or annotation mapping.

I am sure there are more than these four approaches for application specific model data and if you have a suggestion, opinion, question, or comment I would be very keen to hear from you.

8 responses to “Common Reference Data in Spring MVC”

Great post, I’m using a similar technique, but I thought that I would mention that the same sort of thing can also be achieved with most of the html templating options available to Spring MVC. On another note, you should consider using the SemaCodeFix plugin to format your code blocks. I’ve used it with great success on my site. Here is the link: http://www.sematopia.com/?p=138

You are absolutely right, there is no doubt that using an interceptor can be over kill, but in some cases it can be the best solution. Maybe the reference data being added to every page is from the database or maybe you have different properties files for different deployments and would like the information in the properties files be added to every page. In any case, an interceptor is not a perfect solution.

On another note, I am a big fan of sitemesh and agree that templating can be a great substitute.

Thank you also for the link to SemaCodeFix, sadly I can’t use it as I’m using wordpress.com as my blog host, but I will remember it if in case I move my post in the future.

Post data can also be read, just launch up firebug and you will see :).
Exposing the model in the url should not be considered a security risk, instead you should design the security layers with this in mind.

Thanks for the article but i couldn’t understand one part. posthandle will start to work after the controller has finished its work. So my question is how can i use the ModelAndView object of the postHandle before rendering the page?