前言
以下部分内容来自官方文档
文档描述
- @Controller
使用@Controller注解定义一个控制器,@Controller注解表明了一个类是作为控制器的角色而存在的。Spring不要求你去继承任何控制器基类,也不要求你去实现Servlet的那套API。上一节讲的DispatcherServlet会扫描所有注解了@Controller的类,检测其中通过@RequestMapping注解配置的方法。
- @RequestMapping
你可以使用@RequestMapping注解来将请求URL,如/appointments等,映射到整个类上或某个特定的处理器方法上。一般来说,类级别的注解负责将一个特定(或符合某种模式)的请求路径映射到一个控制器上,同时通过方法级别的注解来细化映射,即根据特定的HTTP请求方法(“GET”“POST”方法等)、HTTP请求中是否携带特定参数等条件,将请求映射到匹配的方法上。
@Controller
@RequestMapping("/appointments")
public class AppointmentsController {
private final AppointmentBook appointmentBook;
@Autowired
public AppointmentsController(AppointmentBook appointmentBook) {
this.appointmentBook = appointmentBook;
}
@RequestMapping(method = RequestMethod.GET)
public Map<String, Appointment> get() {
return appointmentBook.getAppointmentsForToday();
}
@RequestMapping(path = "/{day}", method = RequestMethod.GET)
public Map<String, Appointment> getForDay(@PathVariable @DateTimeFormat(iso=ISO.DATE) Date day, Model model) {
return appointmentBook.getAppointmentsForDay(day);
}
@RequestMapping(path = "/new", method = RequestMethod.GET)
public AppointmentForm getNewForm() {
return new AppointmentForm();
}
@RequestMapping(method = RequestMethod.POST)
public String add(@Valid AppointmentForm appointment, BindingResult result) {
if (result.hasErrors()) {
return "appointments/new";
}
appointmentBook.addAppointment(appointment);
return "redirect:/appointments";
}
}
在上面的示例中,许多地方都使用到了@RequestMapping注解。
1) 第一次使用点是作用于类级别的,它指示了所有/appointments开头的路径都会被映射到控制器下。
2) get()方法上的@RequestMapping注解对请求路径进行了进一步细化:它仅接受GET方法的请求。这样,一个请求路径为/appointments、HTTP方法为GET的请求,将会最终进入到这个方法被处理。
3) add()方法也做了类似的细化,而getNewForm()方法则同时注解了能够接受的请求的HTTP方法和路径。这种情况下,一个路径为appointments/new、HTTP方法为GET的请求将会被这个方法所处理。
4) 类级别的@RequestMapping注解并不是必须的。
5) 不配置的话则所有的路径都是绝对路径,而非相对路径。@RequestMapping注解默认会映射所有的HTTP请求方法。如果仅想接收某种请求方法,请在注解中指定之@RequestMapping(method=GET)以缩小范围。
6) getForDay()方法则展示了使用@RequestMapping注解的另一个技巧:URI模板。(下面会讲到)
url模板
URI模板可以为快速访问@RequestMapping中指定的URL的一个特定的部分提供很大的便利。URI模板是一个类似于URI的字符串,只不过其中包含了一个或多个的变量名。当你使用实际的值去填充这些变量名的时候,模板就退化成了一个URI。在URI模板的RFC提议中定义了一个URI是如何进行参数化的。比如说,一个这个URI模板http://www.example.com/users/{userId}就包含了一个变量名userId。将值fred赋给这个变量名后,它就变成了一个URI:http://www.example.com/users/...。在Spring MVC中你可以在方法参数上使用@PathVariable注解,将其与URI模板中的参数绑定起来:
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模板中对应部分的值所填充。比如说,如果请求的URI是/owners/fred,此时变量ownerId的值就是fred.
或者也可以在注解中声明,然后使用别名的参数名:
@RequestMapping(path="/owners/{ownerId}}", method=RequestMethod.GET)
public String findOwner(@PathVariable("ownerId") String theOwner, Model model) {
// 具体的方法代码…
}
一个方法可以拥有任意数量的@PathVariable注解:
@RequestMapping(path="/owners/{ownerId}/pets/{petId}", method=RequestMethod.GET)
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";
}
URI模板可以从类级别和方法级别的 @RequestMapping 注解获取数据。因此,像这样的findPet()方法可以被类似于/owners/42/pets/21这样的URL路由并调用到:
_@Controller_
@RequestMapping("/owners/{ownerId}")
public class RelativePathUriTemplateController {
@RequestMapping("/pets/{petId}")
public void findPet(_@PathVariable_ String ownerId, _@PathVariable_ String petId, Model model) {
// 方法实现体这里忽略
}
}
@PathVariable可以被应用于所有 简单类型 的参数上,比如int、long、Date等类型。Spring会自动地帮你把参数转化成合适的类型,如果转换失败,就抛出一个TypeMismatchException。如果你需要处理其他数据类型的转换,也可以注册自己的类。同时你也可以学习带正则表达式的URL模板。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。