Spring框架@RequestMapping完整指南

Spring Boot 提供了一组新的 REST 请求注释,可以简化构建 RESTful Web 服务的过程。

在Spring 4.3之前,我们使用@RequestMapping注解来实现RESTful的URL映射:

@RequestMapping(value = "/hello", method = RequestMethod.GET)
 public String traditionalMapping(){
   return
"hello";
}

在Spring 4.3之后,拓展简化了@RequestMapping的方法级别注解,新的方法注释更加简洁且更易于阅读。它们还提供更具体的功能,并有助于减少构建 RESTful Web 服务所需的样板代码量。

@RequestMapping
用于在Spring MVC 控制器中映射 Web 请求方法的注释。Spring MVC 和 Spring WebFlux都支持此注释。

@RequestMapping注解提供了多个选项来自定义其行为。

  • consumes – 映射请求的消耗媒体类型,缩小主映射范围。(例如@RequestMapping(consumes = {"application/json", "application/xml"}))。
  • method – 要映射的 HTTP 请求方法(例如method = {RequestMethod.GET,RequestMethod.POST}).
  • header – 映射请求的标头。
  • name – 映射的名称。
  • value – 该注释表达的主要映射
  • produces  – 映射请求的可产生媒体类型。
  • params - 提供了一种有条件地将处理程序方法映射到包含某些具有预期值的参数的请求的方法。

代码:

@Controller
public class SpringMVCController {

 @RequestMapping(value = {
  "/greetings",
 
"/hello-world"}, method = {RequestMethod.GET,RequestMethod.POST}, 
   consumes = {
"application/json","application/xml"}, 
   produces = {
"application/json"},headers = {"application/json"
  })
 public String hellpWorld() {
  return
"Hello";
 }
}

该注解可在类和方法级别使用:

@Controller
@RequestMapping(value = {
 "/greetings"
}, method = {
 RequestMethod.GET
})
public class SpringMVCController {}

以下是params的代码:

@RequestMapping(value = "/products", params = "category=electronics")
public String listElectronicProducts() {
   
// ...
}

在@RequestMapping注释params中指定属性,并以逗号分隔列表的形式提供一个或多个参数约束:

params还用于:
当请求到达时:

  • Spring 会检查请求的 URL 是否与 @RequestMapping 的值属性匹配。
  • 如果匹配,它会检查请求参数是否满足 params 条件。
  • 如果参数匹配,就会调用相关的处理程序方法。

用法:
参数限制:

  • 可以使用简单的相等检查(例如,类别=电子产品)。
  • 可以用逗号组合多个限制条件(例如,类别=电子产品,价格>500)。
  • 您可以使用 SpEL 表达式来实现更复杂的逻辑。

可选参数:
  • 要使参数成为可选参数,可在其名称前加上 !:

@RequestMapping(value = "/search", params = "!q")
public String search() {
   
// ...
}

与其他属性不排斥:
params 属性可与method, headers等其他 @RequestMapping 属性结合使用,以创建更精细的映射。

@Controller
public class ProductController {

    @RequestMapping(value = "/products", method = RequestMethod.GET, params = "category=electronics")
    public String listElectronicProducts() {
       
// Handle requests for electronic products
        return
"electronicProducts";
    }

    @RequestMapping(value =
"/products", method = RequestMethod.GET, params = "!category")
    public String listAllProducts() {
       
// Handle requests for all products
        return
"allProducts";
    }
}

params 属性是细粒度请求映射的强大工具,可确保处理程序方法只调用具有预期参数的请求。

@RequestMapping中四个简化方法注解
从 Spring 4.3 开始,可以在@RequestMapping注释的类的方法中,使用 @GetMapping、@PostMapping、@PutMapping、@DeleteMapping 等更具体的注解,它们是 与特定 HTTP 方法的快捷方式。

  • @GetMapping => @RequestMapping(method = RequestMethod.GET)
  • @PostMapping => @RequestMapping(method = RequestMethod.POST)
  • @PutMapping => @RequestMapping(method = RequestMethod.PUT)
  • @DeleteMapping =>@RequestMapping(method = RequestMethod.DELETE)


1、@GetMapping 方法注解
该注解用于处理 HTTP GET 请求。可以将其翻译为@RequestMapping(method = RequestMethod.GET). 它接受以下参数:

  • value:一个字符串,指定此方法应处理的 URL 路径。
  • produces:一个字符串或字符串数​​组,指定此方法生成的响应的媒体类型。
  • params:一个字符串数组,指定调用此方法必须存在的请求参数。
  • headers:一个字符串数组,指定调用此方法必须存在的标头。

代码:
@RestController
@RequestMapping("/example")
public class MyController {

    @GetMapping(
"/path")
    public String exampleMethod() {
        return
"Hello, this is an example!";
    }
}

在上例中,@GetMapping("/path") 等同于 @RequestMapping(value="/path",method=RequestMethod.GET)。它提供了一种更简洁的方式来表达特定 HTTP 方法的映射。


2、@PostMapping 方法注解
该注解用于处理 HTTP POST 请求。可以将其翻译为@RequestMapping(method = RequestMethod.POST). 它接受以下参数:

  • value:一个字符串,指定此方法应处理的 URL 路径。
  • consumes:一个字符串或字符串数​​组,指定此方法使用的请求正文的媒体类型。
  • produces:一个字符串或字符串数​​组,指定此方法生成的响应的媒体类型。
  • params:一个字符串数组,指定调用此方法必须存在的请求参数。
  • headers:一个字符串数组,指定调用此方法必须存在的标头。

@PostMapping 注解是 @RequestMapping 注解的一种特殊形式,专门用于处理 HTTP POST 请求。它通常与 @RestController 结合使用,用于定义处理传入 POST 请求的方法。

@RestController
public class MyController {

    @PostMapping("/create")
    public String createResource(@RequestBody String requestBody) {
       
// // 处理传入的 POST 请求正文并执行某些操作
        return
"Resource created successfully";
    }
}

  • @RestController:表示该类是控制器,方法的返回值应直接写入响应体。
  • @PostMapping("/create"):指定 createResource 方法应处理路径为"/create "的 HTTP POST 请求。
  • @RequestBody:表示方法参数应绑定到 HTTP 请求正文。在这种情况下,requestBody 参数将填充 POST 请求正文的内容。

您也可以使用 @RequestBody 将更复杂的对象作为方法参数,Spring 会尝试将请求正文反序列化为指定的对象类型。

@RestController
public class MyController {

    @PostMapping("/create")
    public ResponseEntity<String> createResource(@RequestBody CreateRequest createRequest) {
       
// Process the incoming CreateRequest and perform some action
        return ResponseEntity.ok(
"Resource created successfully");
    }
}

在上例中,CreateRequest 是一个 Java 类,代表了预期请求正文的结构。Spring 会自动将传入的 JSON 或表单数据反序列化为 CreateRequest 的实例。

下面是Post输入一个对象,输出也是一个对象的代码:

@PostMapping("/users")
public ResponseEntity<User> createUser(@RequestBody User user) {
    User savedUser = userService.createUser(user);
    return ResponseEntity.created(URI.create(
"/users/" + savedUser.getId())).body(savedUser);
}

上例中,使用 @PostMapping 处理创建新用户的 HTTP POST 请求。value 参数指定了 URL 路径(默认),而 @RequestBody 注解则用于从请求正文中提取用户对象。ResponseEntity 用于在响应头中返回 201 Created 状态代码和新创建用户的位置。

3、@PutMapping 方法注解
该注解用于处理 HTTP PUT 请求。可以将其翻译为@RequestMapping(method = RequestMethod.PUT). 并且它接受与 相同的参数@PostMapping。

@PutMapping("/users/{userId}")
public User updateUser(@PathVariable Long userId, @RequestBody User updatedUser) {
    return userService.updateUser(userId, updatedUser);
}

此示例演示如何使用@PutMapping处理更新用户的 HTTP PUT 请求。参数value指定URL路径,@PathVariable注释用于从URL路径中提取用户ID。该@RequestBody注释用于从请求正文中提取更新的用户对象。

4、@DeleteMapping 方法注解
该注释用于处理 HTTP DELETE 请求。可以将其翻译为@RequestMapping(method = RequestMethod.DELETE). 并且它接受与 相同的参数@GetMapping。


@DeleteMapping("/users/{userId}")
public void deleteUser(@PathVariable Long userId) {
    userService.deleteUser(userId);
}

上面示例显示如何使用@DeleteMapping处理删除用户的 HTTP DELETE 请求。参数value指定URL路径,@PathVariable注释用于从URL路径中提取用户ID。

produces和consumes
produces和consumes参数来指定请求和响应正文的格式,如果您想要返回XML格式的数据(具体取决于请求的内容类型),这非常有用。

  • produces参数指定该方法可以产生的媒体类型,即响应主体的格式。
  • consumes参数指定该方法可以消费的媒体类型,即请求体的格式。

@PostMapping("/users", consumes = "application/json", produces = "application/json")
public ResponseEntity<User> createUser(@RequestBody User user) {
    User savedUser = userService.createUser(user);
    return ResponseEntity.created(URI.create(
"/users/" + savedUser.getId())).body(savedUser);
}

@PostMapping 注解指定该方法应处理对 /users 端点的 HTTP POST 请求。consumes 参数指定该方法只能接收 JSON 格式的请求,produces 参数指定响应也应为 JSON 格式。

您还可以使用字符串数组指定多种媒体类型,如下所示:

@GetMapping("/users/{id}", produces = { "application/json", "application/xml" })
public ResponseEntity<User> getUser(@PathVariable Long id) {
    User user = userService.getUser(id);
    return ResponseEntity.ok().body(user);
}

在上例中,@GetMapping 注解指定该方法应处理对 /users/{id} 端点的 HTTP GET 请求。produces 参数指定该方法可以生成 JSON 和 XML 格式的响应,Spring Boot 将根据请求的内容类型自动选择合适的格式。

方法内参数注解
1、@RequestBody注解读取请求体
Spring Boot 提供@RequestBody注释将 HTTP POST、PUT 或 PATCH 请求的请求正文绑定到控制器中的方法参数。当您需要从请求正文中提取数据时(例如创建或更新资源时),此注释非常有用。

@RequestBody:将请求正文内容(例如,JSON)映射到对象。

@PostMapping("/users")
public User createUser(@RequestBody User user) {
   
// ...
}

默认情况下,Spring Boot 使用 Jackson 将请求正文反序列化为 Java 对象。您可以使用Jackson注释(例如@JsonFormat和 )自定义反序列化过程@JsonProperty。

如果请求正文无效或不存在,Spring Boot400 Bad Request默认返回响应。您可以使用异常处理来自定义响应。

除了 JSON 之外,Spring Boot 还支持其他媒体类型,例如 XML 和表单数据。您可以使用请求映射注释的consumes属性指定媒体类型:

@PostMapping(value = "/users", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ResponseEntity<User> createUser(@RequestBody MultiValueMap<String, String> formData) {
   
// ...
}

2、@PathVariable 注释从请求 URI 中提取值
要使用@PathVariable注释,只需将其添加在方法定义中的参数之前即可。参数名称应与 URI 模板变量名称匹配。这是一个例子:

@GetMapping("/users/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
    User user = userService.getUserById(id);
    return ResponseEntity.ok(user);
}

在上例中,@PathVariable Long id 将 id 参数绑定到 URI 模板 /users/{id} 中的 id 变量。因此,如果向 /users/1 发送 GET 请求,将提取值 1 并传递给 getUserById() 方法。


也可以在 @PathVariable 注解中指定 URI 模板变量名,以防与参数名不匹配。下面是一个例子:

@GetMapping("/users/{userId}/posts/{postId}")
public ResponseEntity<Post> getPostByUserIdAndPostId(@PathVariable(
"userId") Long userId, @PathVariable("postId") Long postId) {
    Post post = postService.getPostByUserIdAndPostId(userId, postId);
    return ResponseEntity.ok(post);
}

在上例中,@PathVariable("userId") Long userId 将 userId 参数绑定到 URI 模板 /users/{userId}/posts/{postId} 中的 userId 变量,而 @PathVariable("postId") Long postId 则将 postId 参数绑定到同一 URI 模板中的 postId 变量。


3、@RequestParam:从HTTP请求中提取查询参数或表单数据。

@GetMapping("/search")
public String search(@RequestParam String query, @RequestParam int page) {
   
// ...
}

4、@RequestHeader:访问 HTTP 请求标头。

@GetMapping("/users")
public List<User> getUsers(@RequestHeader(
"Accept-Language") String language) {
   
// ...
}