Contents

Spring MVC 注解

1.概述

在本教程中,我们将探索org.springframework.web.bind.annotation包中的 Spring Web 注释。

2. @RequestMapping

简单地说, @RequestMapping 标记了*@Controller*类内部的请求处理方法;可以使用以下方式进行配置:

  • path,或其别名name和*value: *方法映射到哪个 URL
  • *method:*兼容的 HTTP 方法
  • *params:*根据 HTTP 参数的存在、不存在或值过滤请求
  • *headers:*根据 HTTP 标头的存在、不存在或值过滤请求
  • *consumes:*该方法可以在 HTTP 请求正文中消费哪些媒体类型
  • *produces:*该方法可以在 HTTP 响应正文中产生哪些媒体类型

这是一个简单的示例:

@Controller
class VehicleController {
    @RequestMapping(value = "/vehicles/home", method = RequestMethod.GET)
    String home() {
        return "home";
    }
}

如果我们在类级别应用此注解,我们可以为@Controller*类中的所有处理程序方法提供默认设置。唯一的例外是 Spring 不会使用方法级别设置覆盖*但附加两个路径部分的 URL。 例如,下面的配置和上面的效果是一样的:

@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 请求的主体映射到一个对象:

@PostMapping("/save")
void saveVehicle(@RequestBody Vehicle vehicle) {
    // ...
}

反序列化是自动的,取决于请求的内容类型。

4. @PathVariable

接下来,让我们谈谈*@PathVariable*。

此注释指示方法参数绑定到 URI 模板变量。我们可以使用*@RequestMapping注解指定 URI 模板,并使用@PathVariable*将方法参数绑定到模板部分之一。

我们可以使用*name 或其别名value *参数来实现这一点:

@RequestMapping("/{id}")
Vehicle getVehicle(@PathVariable("id") long id) {
    // ...
}

如果模板中部分的名称与方法参数的名称匹配,我们不必在注解中指定:

@RequestMapping("/{id}")
Vehicle getVehicle(@PathVariable long id) {
    // ...
}

此外,我们可以通过将required的参数设置为 false来将路径变量标记为可选:

@RequestMapping("/{id}")
Vehicle getVehicle(@PathVariable(required = false) long id) {
    // ...
}

5. @RequestParam

我们使用*@RequestParam*来访问 HTTP 请求参数

@RequestMapping
Vehicle getVehicleByParam(@RequestParam("id") long id) {
    // ...
}

它具有与*@PathVariable*注解相同的配置选项。

除了这些设置之外,当 Spring 在请求中发现没有值或为空值时,我们可以使用*@RequestParam指定注入值。为此,我们必须设置defaultValue*参数。

提供默认值隐式设置requiredfalse

@RequestMapping("/buy")
Car buyCar(@RequestParam(defaultValue = "5") int seatCount) {
    // ...
}

除了参数之外,我们还可以访问其他 HTTP 请求部分:cookies 和 headers。我们可以分别使用注解*@CookieValue@RequestHeader*来访问它们。

我们可以像*@RequestParam*一样配置它们。

6. 响应处理注解

在接下来的部分中,我们将看到在 Spring MVC 中操作 HTTP 响应的最常见注释。

6.1. @ResponseBody

如果我们用@ResponseBody 标记请求处理程序方法,Spring 会将方法的结果视为响应本身

@ResponseBody
@RequestMapping("/hello")
String hello() {
    return "Hello World!";
}

如果我们用这个注解来注解*@Controller*类,所有请求处理程序方法都将使用它。

6.2. @ExceptionHandler

通过这个注解,我们可以声明一个自定义的错误处理方法。当请求处理程序方法抛出任何指定的异常时,Spring 调用此方法。

捕获的异常可以作为参数传递给方法:

@ExceptionHandler(IllegalArgumentException.class)
void onIllegalArgumentException(IllegalArgumentException exception) {
    // ...
}

6.3. @ResponseStatus

如果我们使用此注释对请求处理程序方法进行注释,则可以指定响应的所需 HTTP 状态。我们可以使用code参数或其别名value参数来声明状态码。

此外,我们可以使用reason参数提供原因。

我们也可以将它与*@ExceptionHandler*一起使用:

@ExceptionHandler(IllegalArgumentException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
void onIllegalArgumentException(IllegalArgumentException exception) {
    // ...
}

有关 HTTP 响应状态的更多信息,请访问这篇文章

7. 其他网页注解

一些注释不直接管理 HTTP 请求或响应。在接下来的部分中,我们将介绍最常见的。

7.1. @Controller

我们可以使用*@Controller*定义一个 Spring MVC 控制器。有关更多信息,请访问我们关于 Spring Bean Annotations 的文章

7.2. @RestController

@RestController结合了*@Controller* 和*@ResponseBody*。

因此,以下声明是等效的:

@Controller
@ResponseBody
class VehicleRestController {
    // ...
}
@RestController
class VehicleRestController {
    // ...
}

7.3. @ModelAttribute

通过这个注解,我们可以通过提供模型键来访问已经存在于MVC @Controller模型中的元素:

@PostMapping("/assemble")
void assembleVehicle(@ModelAttribute("vehicle") Vehicle vehicleInModel) {
    // ...
}

与*@PathVariable@RequestParam*一样,如果参数具有相同的名称,我们不必指定模型键:

@PostMapping("/assemble")
void assembleVehicle(@ModelAttribute Vehicle vehicle) {
    // ...
}

此外,@ModelAttribute还有一个用途:如果我们用它注解一个方法,Spring 会自动将方法的返回值添加到模型中

@ModelAttribute("vehicle")
Vehicle getVehicle() {
    // ...
}

和以前一样,我们不必指定模型键,Spring 默认使用方法的名称:

@ModelAttribute
Vehicle vehicle() {
    // ...
}

在 Spring 调用请求处理程序方法之前,它会调用类中所有*@ModelAttribute*注解的方法。

有关@ModelAttribute的更多信息,请参阅本文

7.4. @CrossOrigin

@CrossOrigin 为带注释的请求处理程序方法启用跨域通信

@CrossOrigin
@RequestMapping("/hello")
String hello() {
    return "Hello World!";
}

如果我们用它标记一个类,它适用于其中的所有请求处理程序方法。

我们可以使用此注释的参数微调 CORS 行为。

有关更多详细信息,请访问本文