18.5 重定向和Flash属性

18.5 重定向和Flash属性

作为一个经验丰富的Servlet/JSP程序员,必须知道转发和重定向的区别转发比重定向快,因为重定向经过客户端,而转发没有。但是,有时采用重定向更好。

  • 若需要引入到一个外部网站,则无法使用转发,因该使用重定向
  • 另一个使用重定向的场景避免在用户重新加载页面时再次调用同样的动作

例如,在app18a中,当提交产品表单时,saveProduct方法将被调用,并执行相应的动作。在一个真实的应用程序中,这可能包括将所述产品加入到数据库中。但是,如果在提交表单后重新加载页面,saveProduct就会被再次调用,同样的产品将可能被再次添加为了避免这种情况提交表单后,你可能更愿意将用户重定向到一个不同的页面。这个网页任意重新加载都没有副作用。例如,在app18a中,可以在提交表单后,将用户重定向到一个ViewProduct页面。
app18b中,ProductController类中的saveProduct方法以如下所示的行结束:

1
return "redirect:/product_view/" + savedProduct.getId();

这里,使用重定向,而不是转发来防止当用户重新加载页面时,saveProduct被二次调用

使用重定向的一个不便的地方是:无法轻松地传值给目标页面。
而采用转发,则可以简单地将属性添加到Model,使得目标视图可以轻松访问。由于重定向经过客户端,所以Model中的一切都在重定向时丢失。
幸运的是,Spring 3.1版本以及更高版本通过**Flash属性提供了一种供重定向传值的方法**。
要使用Flash属性,必须在Spring MVC配置文件中有一个<annotation-driven/>元素。然后,还必须在方法上添加一个新的参数类型
org.springframework.web.servlet.mvc.support.RedirectAttribute

下面的代码展示了更新后的saveProduct方法。

使用Flash属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@RequestMapping(
value = "product_save",
method = RequestMethod.POST
)
public String saveProduct(ProductForm productForm,
RedirectAttributes redirectAttributes)
{
logger.info("saveProduct called");
// no need to create and instantiate a ProductForm
// create Product
Product product = new Product();
product.setName(productForm.getName());
product.setDescription(productForm.getDescription());
try {
product.setPrice(Float.parseFloat(productForm.getPrice()));
} catch (NumberFormatException e) {
}
// add product
Product savedProduct = productService.add(product);
redirectAttributes.addFlashAttribute("message",
"The product was successfully added.");
return "redirect:/product_view/" + savedProduct.getId();
}