- 
                Notifications
    
You must be signed in to change notification settings  - Fork 3.7k
 
@MVC Flash Attribute Support
Description:
Attributes present in the model that match the @FlashAttributes annotation are added to flash storage if the controller redirects.
Example:
@Controller
@FlashAttributes("successMessage")
public class MessageController {
	@RequestMapping(value = "/messages", method = RequestMethod.POST)
	public String sendMessage(TestBean testBean, BindingResult result, Model model) {
		if (result.hasErrors()) {
			return "messages/new";
		}
		else {
			model.addAttribute("id", "1").addAttribute("name", "value").addAttribute("successMessage", "yay!");
			return "redirect:/messages/{id}";
		}
	}
}Advantages:
- There is only one interface for adding attributes of any kind
 - Consistent with 
@SessionAttributes - Does not require additional method arguments
 - Syncs the model transparently
 
Things to Consider:
- 
@FlashAttributesmay contain a mix of attributes applicable to different redirect scenarios - A degree of duplication if you need to add a flash attribute and then list it
 - It's not obvious if 
@FlashAttributesmeans attributes to store or to retrieve? Since@FlashAttributeslists attributes for different redirect scenarios, using the same list to retrieve can become confusing 
Description:
A ResponseContext method argument provides convenience methods for selecting a view to render and to redirect. Note that for a redirect the implicit model is ignored allowing precise control over the attributes used.
Example:
@Controller
public class MessageController {
	@RequestMapping(value = "/messages", method = RequestMethod.POST)
	public void sendMessage(TestBean testBean, BindingResult result, ResponseContext responseContext) {
		if (result.hasErrors()) {
			responseContext.view("messages/new");
		}
		else {
			responseContext.redirect("redirect:/messages/{id}").uriVariable("id", "1").queryParam("name", "value")
					.flashAttribute("successMessage", "yay!");
		}
	}
}Advantages:
- Flash attributes can be specified just once (if not already present in the model)
 - Precise control over the model on a redirect (SPR-1068, SPR-1294, SPR-6796)
 
Things to Consider:
- A method must return void and that can only be verified (and flagged as an error) at runtime
 - Prevents customizing response handling (
HandlerMethodReturnValueHandler,ModelAndViewResolver) - A degree of duplication when attributes (uri vars, query param, flash attrs) are already in the model
 - No clean way of returning a RedirectView or a RedirectView sub-type
 
Description:
A ResponseInstruction return value is used to select a view to render or to redirect. This is similar to the ResponseContext method argument option but using a return value.
Example:
@Controller
public class MessageController {
	@RequestMapping(value = "/messages", method = RequestMethod.POST)
	public ResponseInstruction sendMessage(TestBean testBean, BindingResult result) {
		if (result.hasErrors()) {
			return new ViewInstruction("messages/new");
		}
		else {
			return new RedirectInstruction("redirect:/messages/{id}").uriVariable("id", "1")
					.queryParam("name", "value").flashAttribute("successMessage", "yay!");
		}
	}
}Advantages:
- Same as for RedirectContext
 
Things to Consider:
- More verbose than returning a String view name
 - It becomes necessary to use 
new ViewInstruction("messages/new")without benefit - No clean way of returning a RedirectView or a RedirectView sub-type
 
Description:
Controller method declares a RedirectModel method argument, which @MVC uses instead of the implicit model if the controller redirects. Initially the redirect model is empty allowing precise control over the attributes used.
Example:
@Controller
public class MessageController {
	@RequestMapping(value = "/messages", method = RequestMethod.POST)
	public String sendMessage(TestBean testBean, BindingResult result, RedirectModel redirectModel) {
		if (result.hasErrors()) {
			return "messages/new";
		}
		else {
			redirectModel.addAttribute("id", "1").addAttribute("name", "value")
					.addFlashAttribute("successMessage", "yay!");
			return "redirect:/messages/{id}";
		}
	}
}Advantages:
- Flash attributes can be specified just once (if not already present in the model)
 - Precise control over the model on a redirect (SPR-1068, SPR-1294, SPR-6796)
 
Things to Consider:
- Although RedirectModel is a Model, flash attributes aren't treated as other model attributes.
 - Having a different kind of model for what is a rendering concern seems backwards.
 - A degree of duplication for attribute that are already in the model
 
Description:
@RedirectAttributes annotation lists attributes to be used if the controller method redirects.
Example:
@Controller
public class MessageController {
	@RequestMapping(value = "/messages", method = RequestMethod.POST)
    @RedirectAttributes(value = {"id", "name"}, flash = "successMessage")
	public String sendMessage(TestBean testBean, BindingResult result, Model model) {
		if (result.hasErrors()) {
			return "messages/new";
		}
		else {
			model.addAttribute("id", "1").addAttribute("name", "value").addAttribute("successMessage", "yay!");
			return "redirect:/messages/{id}";
		}
	}
}Advantages:
- There is only one interface for adding attributes of any kind
 - Does not require additional method arguments
 - Precise control over the model on a redirect (SPR-1068, SPR-1294, SPR-6796)
 - Syncs the model transparently
 
Things to Consider:
- A degree of duplication if you need to add a flash attribute and then list it.