7.5.1 通过 URL 模板进行重定向

通过路径变量和查询参数传递数据看起来非常简单。例如,在程序清单 5.19 中,我们以路径变量的形式传递了新创建 Spitter 的 username。但是按照现在的写法,username 的值是直接连接到重定向 String 上的。这能够正常运行,但是还远远不能说没有问题。当构建 URL 或 SQL 查询语句的时候,使用 String 连接是很危险的。

return "redirect:/spitter/{username}";

除了连接 String 的方式来构建重定向 URL,Spring 还提供了使用模板的方式来定义重定向 URL。例如,在程序清单 5.19 中,processRegistration() 方法的最后一行可以改写为如下的形式:

@RequestMapping(value="/register", method=POST);
public String processRegistration(
    Spitter spitter, Model model) {
  spitterRepository.save(spitter);
  
  model.addAttribute("username", spitter.getUsername());
  return "redirect:/spitter/{username}";
}

现在,username 作为占位符填充到了 URL 模板中,而不是直接连接到重定向 String 中,所以 username 中所有的不安全字符都会进行转义。这样会更加安全,这里允许用户输入任何想要的内容作为 username,并会将其附加到路径上。

除此之外,模型中所有其他的原始类型值都可以添加到 URL 中作为查询参数。作为样例,假设除了 username 以外,模型中还要包含新创建 Spitter 对象的 id 属性,那 processRegistration() 方法可以改写为如下的形式:

@RequestMapping(value="/register", method=POST)
public String processRegistration(
    Spitter spitter, Model model) {
  spitterRepository.save(spitter);
  model.addAttribute("username", spitter.getUsername());
  model.addAttribute("spitterId", spitter.getId());
  return "redirect:/spitter/{username}";
}

所返回的重定向 String 并没有太大的变化。但是,因为模型中的 spitterId 属性没有匹配重定向 URL 中的任何占位符,所以它会自动以查询参数的形式附加到重定向 URL 上。

如果 username 属性的值是 habuma 并且 spitterId 属性的值是 42,那么结果得到的重定向 URL 路径将会是 /spitter/habuma?spitterId=42

通过路径变量和查询参数的形式跨重定向传递数据是很简单直接的方式,但它也有一定的限制。它只能用来发送简单的值,如 String 和数字的值。在 URL 中,并没有办法发送更为复杂的值,但这正是 flash 属性能够提供帮助的领域。

Last updated