views:

694

answers:

3

I am building an application using Spring MVC. I want to make certain changes to my Model for every Controller in the application. In particular, I want to insert certain extra data into the model which will be present for all pages of the application.

I could do this several ways: just add the data at the end of every Controller, use a subclass of Model that adds my extra data, use a subclass of ModelAndView that wraps my Model, use a subclass of VelocityView that wraps the Model before using it... I'm sure there are other options.

But I have an "elegance" constraint: I don't want to write code in each and every Controller, I want this behavior defined in one-and-only-one place. Ideally, it would be controlled by my IOC bean config file.

Does anyone have a recommendation of how to achieve this elegantly?

+1  A: 

You could take a look at using Aspects. Spring even has an AOP extension that you could use.

In brief an aspect would allow you to define code once that would then get "woven" into your classes either when you compile the classes or when they are loaded by the classloader. It's relatively advanced stuff and isn't the most intuitive thing for new programmers to pick up, but it's intended to solve exactly the problem you're referring to.

Mike Deck
+4  A: 

Aspects are a good approach, but Spring MVC makes it even easier -- you can define a HandlerInterceptor that will be called before or after every time a request is handled. In the HandlerInterceptor postHandle method (in your class that implements the HandlerInterceptor interface) you can add your data to the ModelAndView. You define which handlers should be intercepted in your config file.

JacobM
Thank you! That's exactly what I was looking for.
mcherm
A: 

I might be wrong, but I suspect that you may have described your requirements incorrectly.

You seem to be saying 'I want certain data to be added to my model, for all controllers'.

I suspect that you mean 'I want certain data to be available for all views'.

If my suspicions are correct, then adding the data to you model is polluting your model and violating the single responsibility principle. This is especially true if the same data is to be added to several models. Be careful that you are not just using your model as a convenient 'carrier' of the data - where the data doesn't really have anything to do with the model.

Admittedly, I'm not completely familiar with the Spring MVC way of doing things, but a more detailed example of what you're trying to achieve may allow for a more informed discussion.

belugabob
I am not sure I quite understand the distinction you are making -- I thought "the model" in Spring was "the data available to the views". If there's a different way of making data available to the view, what is it?
mcherm
Well, if you think about the referenceData method in SimpleFormController, that's an example of "making information available to the views" without putting it in the model. But yeah, belugabob's single responsibility objection would only apply if the model was a single object, but it's a map.
JacobM
Isn't there a distinction between the 'Model' and the 'Value stack'?Data in the Model is directly related to the task being carried out, data in the value stack is often used to support this. A single country is often part of the model, all countries is often supporting data.
belugabob