Archive

Posts Tagged ‘needbetterdocs’

Spring Framework Annotation @SessionAttributes can be confusing

February 11th, 2008 3 comments

I spent a fair amount of time banging my head against the wall trying to figure out how @SessionAttributes works in Spring’s annotations. The concept and implementation is fairly simple, the use and lack of documentation is confusing. Here’s your standard usage:

@Controller@RequestMapping("/someForm.do")
@SessionAttributes("fooForm")
public class FooFormController {
	@RequestMapping(method = RequestMethod.GET)
	public String setupForm(ModelMap model) {
 		FooForm fooForm = new FooForm();
 		// populate fooForm
 		model.addAttribute("fooForm", fooForm);
 		return "fooFormDisplayPage.jsp";
 	}

	@RequestMapping(method = RequestMethod.POST)
 	public String processForm(@ModelAttribute("fooForm") FooForm fooForm) {
 		// do something with fooForm
 		status.setComplete();
 		return "redirect:/someOtherView";
	}
}

The way this works is that the object that is inserted into the ModelMap and identified by @SessionAttributes is stored in the session across the life of the controller. The ModelMap object’s lifespan is tied directly to that of the controller object. Despite it’s name, @SessionAttributes has absolutely nothing to do with HttpSession.set/getAttribute(), it’s simply the annotated version of <sessionForm> from the xml version of the Spring configuration. The upshot of this is that the value identified in @SessionAttributes is not available to a different controller.

What if you want to store something in the session across multiple requests? The tried and true method of storing it in the HttpSession is still valid:

@RequestMapping(method = RequestMethod.POST);
public String processForm(@ModelAttribute("fooForm") FooForm fooForm,
                          HttpSession session) {
	// do something with fooForm
        session.setAttribute("fooForm", fooForm);
	status.setComplete();
        return "redirect:/someOtherView";
}

You can also define multiple request mappings inside of the same Controller object

@Controller
public class MultiViewController {
	@RequestMapping("/foo");
	public String handleFooRequest(ModelMap model) {
		// Handle request
	}
	@RequestMapping("/bar");
	public String handleBarRequest(ModelMap model) {
		// Handle request
	}
}

And there you go. Annotations are neat, allow for straight up pojos, and remove a lot of unnecessary XML configuration. Use them, just make sure they are adequately documented.

Categories: Tech Tags: , ,