Spring Web 注解
1、概览
本文将带你了解 org.springframework.web.bind.annotation 包中的 Spring Web 注解。
2、@RequestMapping
简单地说,@RequestMapping 注解用于标记 @Controller 类中的请求处理方法(Handler),可配置的属性如下:
path或其别名name和value:方法映射到的 URLmethod:支持的 HTTP 方法params:内容协商,根据 HTTP 参数的有无或值匹配请求headers:内容协商,根据 HTTP Header 的存在、缺失或值匹配请求consumes:支持的请求媒体类型(Content-Type)produces:响应的媒体类型
示例如下:
@Controller
class VehicleController {
@RequestMapping(value = "/vehicles/home", method = RequestMethod.GET)
String home() {
return "home";
}
}
在 @Controller 类的类级应用此注解,就能为类中的所有 Handler 方法提供默认设置。唯一的例外是 URL,Spring 不会在方法级设置覆盖 URL,而是将两个 path 部分拼接在一起。
例如,以下配置与上述配置效果相同:
@Controller
@RequestMapping(value = "/vehicles", method = RequestMethod.GET)
class VehicleController {
@RequestMapping("/home")
String home() {
return "home";
}
}
此外,@GetMapping、@PostMapping、@PutMapping、@DeleteMapping 和 @PatchMapping 是 @RequestMapping 的不同变体,其 HTTP 方法已分别设置为 GET、POST、PUT、DELETE 和 PATCH。
这些注解自 Spring 4.3 版本后可用。
3、@RequestBody
@RequestBody 将 HTTP 请求体(Payload)封装到 Java 对象:
@PostMapping("/save")
void saveVehicle(@RequestBody Vehicle vehicle) {
// ...
}
这种反序列化是自动进行的,取决于请求的 Content Type。
4、@PathVariable
@PathVariable 用于把 @RequestMapping 注解中的 URI 模板变量绑定到方法参数:
使用 name 或其别名,即 value 参数来实现:
@RequestMapping("/{id}")
Vehicle getVehicle(@PathVariable("id") long id) {
// ...
}
如果模板中的变量名称与方法参数名称一致,就不必在注解中指定:
@RequestMapping("/{id}")
Vehicle getVehicle(@PathVariable long id) {
// ...
}
此外,还可以通过将参数 required 设为 false 来标记 URI 模板变量为可选变量:
@RequestMapping("/{id}")
Vehicle getVehicle(@PathVariable(required = false) long id) {
// ...
}
5、@RequestParam
@RequestParam 用于绑定请求参数:
@RequestMapping
Vehicle getVehicleByParam(@RequestParam("id") long id) {
// ...
}
它的配置选项与 @PathVariable 注解相同。
除此以外,还可以使用 defaultValue 属性指定一个默认值。
提供默认值会隐式地将 required 设为 false:
@RequestMapping("/buy")
Car buyCar(@RequestParam(defaultValue = "5") int seatCount) {
// ...
}
除了参数,还可以分别使用 @CookieValue 和 @RequestHeader 注解访问 Cookie 和 Header。
可以像配置 @RequestParam 一样配置它们。
6、处理响应的注解
接下来看看在 Spring MVC 中操作 HTTP 响应的最常用注解。
6.1、@ResponseBody
如果用 @ResponseBody 标记一个 Handler 方法,Spring 就会将该方法的返回结果视为响应本身,即响应体:
@ResponseBody
@RequestMapping("/hello")
String hello() {
return "Hello World!";
}
如果使用此注解注解 @Controller 类,所有 Handler 方法都将使用它。
6.2、@ExceptionHandler
通过该注解,可以声明一个自定义 Error Handler 方法。当 Handler 方法抛出任何指定异常时,Spring 就会调用该方法。
捕获的异常可以作为参数传递给方法:
@ExceptionHandler(IllegalArgumentException.class)
void onIllegalArgumentException(IllegalArgumentException exception) {
// ...
}
6.3、@ResponseStatus
用于指定 Handler 方法响应的 HTTP 状态码,此外,还可以使用 reason 参数提供一个理由。
通常将其与 @ExceptionHandler 一起使用:
@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
void onIllegalArgumentException(IllegalArgumentException exception) {
// ...
}
7、其他 Web 注解
其他一些不直接管理 HTTP 请求和响应的注解。
7.1、@Controller
@Controller 用于定义 Spring MVC Controller 类。
7.2、@RestController
@RestController 结合了 @Controller 和 @ResponseBody。
因此,以下两个声明是相同的:
@Controller
@ResponseBody
class VehicleRestController {
// ...
}
@RestController
class VehicleRestController {
// ...
}
7.3、@ModelAttribute
使用这个注解,可以通过 Model Key 来访问已经在于 MVC @Controller 的 Model 中的元素:
@PostMapping("/assemble")
void assembleVehicle(@ModelAttribute("vehicle") Vehicle vehicleInModel) {
// ...
}
与 @PathVariable 和 @RequestParam 一样,如果参数具有相同的名称,就不必指定 Model Key:
@PostMapping("/assemble")
void assembleVehicle(@ModelAttribute Vehicle vehicle) {
// ...
}
此外,@ModelAttribute 还有另一个用途:如果用它注解一个方法,Spring 会自动将该方法的返回值添加到 Model 中:
@ModelAttribute("vehicle")
Vehicle getVehicle() {
// ...
}
和之前一样,不必指定 Model Key,Spring 默认使用方法的名称:
@ModelAttribute
Vehicle vehicle() {
// ...
}
在 Spring 调用 Handler 方法之前,它会调用类中的所有 @ModelAttribute 注解方法。
7.4、@CrossOrigin
@CrossOrigin 以注解形式配置跨域(CORS ):
@CrossOrigin
@RequestMapping("/hello")
String hello() {
return "Hello World!";
}
如果用它标记一个类,它就会应用于其中的所有 Handler 方法。
更多关于 @CrossOrigin 注解以及跨域的详细细节,你可以参阅 这篇文章。
8、总结
本文介绍了 Spring 中和 Web 相关的核心注解,还通过示例介绍了它们的使用方法。
Ref:https://www.baeldung.com/spring-mvc-annotations