As I mentioned earlier, I recently moved back to the Java world after a brief and enjoyable foray into Groovy & Grails. After a few minutes of becoming reacquainted with Spring MVC, I found myself wanting to make my Spring MVC app behave more like a Grails app. I’m lazy, what can I say?
The request mapping annotations are the obvious first piece to the puzzle. The second piece is using model attributes. The third is a bit of javascript to get some flexibility in the view. Here we go.
Obviously, the class marked with the ModelAttribute annotation can be an actual model object or a command object.
The controller will look something like this:
/** * A simple controller, use it to display and update values in the command object. * * @author justin */ @Controller public class SampleController { @RequestMapping("/action-to-display-page.do") public ModelAndView displayYourPage() { //build your command object ModelOrCommandObject modelOrCommandObject = new ModelOrCommandObject(); modelOrCommandObject.setMessage("Hello world."); //put your command object in the model map. ModelMap modelMap = new ModelMap(); modelMap.addAttribute("modelOrCommandObject", modelOrCommandObject); //build your ModelAndView object. ModelAndView modelAndView = new ModelAndView(); modelAndView.addAllObjects(modelMap); modelAndView.setViewName("some-page.jsp"); return modelAndView; } /** * One of the actions that your page is submits to. * @param modelOrCommandObject * @param result * @param status * @return */ @RequestMapping("/one-action-to-call.do") public ModelAndView actionOne( @ModelAttribute("modelOrCommandObject") ModelOrCommandObject modelOrCommandObject, BindingResult result, SessionStatus status) { //do whatever you need to with your command or model object for this command modelOrCommandObject.getMessage(); return new ModelAndView(); } /** * Another action that your page submits to. * @param modelOrCommandObject * @param result * @param status * @return */ @RequestMapping("/another-action-to-call.do") public ModelAndView actionTwo( @ModelAttribute("modelOrCommandObject") ModelOrCommandObject modelOrCommandObject, BindingResult result, SessionStatus status) { //do whatever you need to with your command or model object. modelOrCommandObject.getMessage(); return new ModelAndView(); } }
We’ll have the option in the view to map one action to the controller or multiple actions. Multiple actions is easy with a bit of javascript.
The jsp will contain code like this;
<form:form action="/myapp/one-action-to-call.do" method="POST" modelAttribute="command" method="POST">
<!– some form fields –>
<button onclick="this.form.action=’/myapp/one-action-to-call.do’;submit()">One action</button>
<button onclick="this.form.action=’/myapp/another-action-to-call.do’;submit()">Another action</button>
</form:form>
That’s been working well for me as a simple bridge between Spring MVC and *some* of the convenience and efficiency of grails.