Jul 12th, 2012, 03:09 AM
Spring MVC 3.1.2 populating a bean before handler
I'm evaluating Spring MVC 3.1.2 for a new project and I've been trying to do the following thing.
I've a class annotated as @controller and a method marked with @RequestMapping. If I navigate with a browser to the url mapped in the @RequestMapping everything works fine and the handler is called.
My handler method accepts a parameter which is a bean that is filled when the handler is called.
What I would like to do is have the possibility to modify the bean values before it is filled with the data from the request.
I've tried using an HandlerMethodArgumentResolver and this gets called only if there are no annotations on the parameter ( this is not the case as I'm trying to define how to fill the bean using a custom annotation ). From what I've understood custom ArgumentResolvers will not be called if there are annotations. So I should be changing the default ArgumentResolvers but they cannot be configured using the xml because the method setArgumentResolvers of the class RequestMappingHandlerAdapter accepts a List<HandlerMethodArgumentResolver> while the getter returns HandlerMethodArgumentResolverComposite.
So I've create a BeanPostProcessor to call the setArgumentResolvers and change the list of the base resolvers. This is still not working and I get the following exception:
java.lang.IllegalStateException: An Errors/BindingResult argument is expected to be immediately after the model attribute argument in the controller method signature
Now I'm trying to use an HandlerInterceptorAdapter but I'm not sure this is the right way to go.
Has anybody tried to do something like this ?
Jul 12th, 2012, 04:26 AM
And why wouldn't a @ModelAttribute annotated method help you? That is called before the request handling method and yo ucan do anything to populate your object (retrieve it from a db for instance).
For some reason you seem to make it overly complex.
Jul 12th, 2012, 04:45 AM
Thx for answering so fast Marten.
I've thought of the @ModelAttribute annotated method but this is executed every time the controller is called so if I had a database retrieval routine it would be called even if not needed. Also I would need to load from the database a specific object based on an id taken from the web request. Mainly what I'm trying to achieve is to fill the bean with the data on the database corresponding to the item that is going to be updated. I'm trying to do this because some of the properties of the bean will not be present on the form and would be wiped out when updating the record using only the data coming from the form.
Jul 12th, 2012, 04:54 AM
And how many request handling methods do you expect to have? If you have a user edit page I would expect 2 (GET and POST) and for both I would need the user from the database. YOu shouldn't put everything in a single controller but have very small controllers.
Another solution could be is in the get method populate the model and use @SessionAttributes to store it in the session in between requests. That way you only retrieve it one time, drawback is that you now store things in the http session which can be a problem in you want to remain stateless.
Jul 12th, 2012, 08:18 AM
Ok I didn't remember that the @ModelAttribute annotated method could have the same parameters as the @RequestMapping annotated parameter. That's why I didn't think it was a viable solution.
To solve the fact that the method is called many times I get the "org.springframework.web.servlet.HandlerMapping.be stMatchingPattern" attribute in the request to check if it matches the one in the @RequestMapping. I don't know if this is the best way to do it but it seems to work.
Thank you very much Marten.
Jul 14th, 2012, 05:20 AM
Thanks for this topic. It is very informative.
Tags for this Thread