这一部分是对 Spring 5 文档的直接翻译,连接是这个。这一部分的示例不再贴代码,请到这个项目的 mvc 分支下查看,本篇示例的控制器名称是 URITemplateController。
URI 模板可以很方便地用于访问一个 @RequestMapping 方法中的 URL 的被选择的部分。
URI 模板是一个像URI的字符串,它包含一个或多个变量名。当你用值来替代这些变量时,这个模板就会变成一个 URI。为 URI 模板拟定的 RFC 文档定义了一个 URI 是怎样被参数化的。比如,URI 模板 http://www.example.com/users/{userId} 包含一个变量 userId。把值 fred 赋到这个变量中就产生了 http://www.example.com/users/…。
在 Spring MVC 中,你可是在一个方法参数上使用注解 @PathVariable,来把这个参数绑定到一个URI模板变量上:
@GetMapping("/owners/{ownerId}")
public String findOwner(@PathVariable String ownerId, Model model)
{
Owner owner = ownerService.findOwner(ownerId);
model.addAttribute("owner", owner);
return "displayOwner";
}
URI 模板 “/owners/{ownerId}” 指定了一个名叫 ownerId 的变量。当控制器处理这个请求时,ownerId 的值被设置为从 URI 中解析出来的合适的部分。比如,当请求 /owners/fred 进来时,fred 就是 ownerId 的值。
为了处理注解 @PathVariable,Spring MVC 需要按名找到匹配URI模板的变量。你可以在这个注解中指定:
@GetMapping("/owners/{ownerId}")
public String findOwner(@PathVariable("ownerId") String theOwner, Model model)
{
// implementation omitted
}
如果 URI 模板变量名匹配方法参数名,那么你可以省略详细配置。只要你的代码在编译时带有调试信息或者在使用 Java 8 编译时使用参数 -parameters,Spring MVC 就会匹配方法参数名到 URI 模板变量名:
@GetMapping("/owners/{ownerId}")
public String findOwner(@PathVariable String ownerId, Model model)
{
// implementation omitted
}
一个方法可以有任何数量的注解 @PathVariable:
@GetMapping("/owners/{ownerId}/pets/{petId}")
public String findPet(@PathVariable String ownerId, @PathVariable String petId, Model model)
{
Owner owner = ownerService.findOwner(ownerId);
Pet pet = owner.getPet(petId);
model.addAttribute("pet", pet);
return "displayPet";
}
当在一个Map<String, String>
参数上使用 @PathVariable 注解时,这个 Map 会被填上所有的 URI 模板变量。
一个 URI 模板可以被集成到类和方法级别的@RequestMapping 注解上。方法 findPet() 可以被一个 /owners/42/pets/21 这样的 URI 调用。
@Controller
@RequestMapping("/owners/{ownerId}")
public class RelativePathUriTemplateController
{
@RequestMapping("/pets/{petId}")
public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model)
{
// implementation omitted
}
}
一个 @PathVariable 参数可以是任何简单类型,比如 int,long,Date 等。Spring 自动转换到合适的类型,如果转换失败,就抛出一个 TypeMismatchException 异常。你也可以注册自己的数据类型转换支持。参见“方法参数和类型转换”和“自定义 WebDataBinder 初始化”。
在定义URI模板变量时,你需要更高的精确度。考虑 URL“/spring-web/spring-web-3.0.5.jar”。你怎么把它分成几部分呢?
注解 @RequestMapping 支持在 URI 模板变量中使用正则表达式。语法 {varName:regex} 的第一部分定义了变量名,第二部分是一个正则表达式。例如:
@RequestMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{extension:\\.[a-z]+}")
public void handle(@PathVariable String version, @PathVariable String extension)
{
// ...
}