1. 概述

Spring 4.3 引入了一些方法级别的组合注解,以简化典型Spring MVC项目中对@RequestMapping的处理。本文将介绍如何有效地使用它们。

2. 新的注解

传统上,如果我们要使用传统的@RequestMapping注解实现URL处理器,可能会像这样:

@RequestMapping(value = "/get/{id}", method = RequestMethod.GET)

新方法使得我们可以简化为:

@GetMapping("/get/{id}")

Spring目前支持五种内置注解,用于处理不同类型的HTTP请求方法,包括GETPOSTPUTDELETEPATCH。这些注解如下:

  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @DeleteMapping
  • @PatchMapping

从命名约定可以看出,每个注解都对应相应的HTTP请求方法类型,例如@GetMapping用于处理GET请求,@PostMapping处理POST请求等。

3. 工作原理

上述所有注解都已在method元素中内部注解了@RequestMapping和相应的值。

例如,查看@GetMapping注解的源代码,我们可以看到它已经以以下方式注解了RequestMethod.GET

@Target({ java.lang.annotation.ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = { RequestMethod.GET })
public @interface GetMapping {
    // abstract codes
}

其他注解的创建方式相同,例如@PostMapping被注解为RequestMethod.POST@PutMapping被注解为RequestMethod.PUT等。

这些注解的完整源代码可在这里找到。

4. 实现

让我们尝试使用这些注解构建一个快速的REST应用。

请注意,由于我们将使用Maven构建项目并使用Spring MVC创建应用程序,因此我们需要在pom.xml中添加必要的依赖:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.2.RELEASE</version>
</dependency>

最新的spring-webmvc版本可以在中央Maven仓库中找到。

现在,我们需要创建控制器来映射传入的请求URL。在这个控制器中,我们将逐一使用所有这些注解。

4.1. @GetMapping

@GetMapping("/get")
public @ResponseBody ResponseEntity<String> get() {
    return new ResponseEntity<String>("GET Response", HttpStatus.OK);
}
@GetMapping("/get/{id}")
public @ResponseBody ResponseEntity<String>
  getById(@PathVariable String id) {
    return new ResponseEntity<String>("GET Response : " 
      + id, HttpStatus.OK);
}

4.2. @PostMapping

@PostMapping("/post")
public @ResponseBody ResponseEntity<String> post() {
    return new ResponseEntity<String>("POST Response", HttpStatus.OK);
}

4.3. @PutMapping

@PutMapping("/put")
public @ResponseBody ResponseEntity<String> put() {
    return new ResponseEntity<String>("PUT Response", HttpStatus.OK);
}

4.4. @DeleteMapping

@DeleteMapping("/delete")
public @ResponseBody ResponseEntity<String> delete() {
    return new ResponseEntity<String>("DELETE Response", HttpStatus.OK);
}

4.5. @PatchMapping

@PatchMapping("/patch")
public @ResponseBody ResponseEntity<String> patch() {
    return new ResponseEntity<String>("PATCH Response", HttpStatus.OK);
}

注意点:

  • 我们使用了必要的注解来处理适当的HTTP方法和URI。例如,使用@GetMapping处理"/get" URI,@PostMapping处理"/post" URI等。
  • 因为我们正在构建基于REST的应用,所以返回一个与每个请求类型相关的恒定字符串(200响应码),以简化应用程序。在此情况下,我们使用了Spring的@ResponseBody注解。
  • 如果需要处理URL路径变量,我们可以像使用@RequestMapping时那样简单地进行处理。

5. 测试应用

为了测试应用,我们需要使用JUnit创建几个测试用例。我们将使用SpringJUnit4ClassRunner初始化测试类。我们将创建五个不同的测试用例,以测试控制器中声明的每个注解和处理器。

让我们看看@GetMapping的示例测试用例:

@Test 
public void giventUrl_whenGetRequest_thenFindGetResponse() 
  throws Exception {

    MockHttpServletRequestBuilder builder = MockMvcRequestBuilders
      .get("/get");

    ResultMatcher contentMatcher = MockMvcResultMatchers.content()
      .string("GET Response");

    this.mockMvc.perform(builder).andExpect(contentMatcher)
      .andExpect(MockMvcResultMatchers.status().isOk());

}

如您所见,当我们发送GET请求到"/get"时,我们期望得到字符串"GET Response"。

现在,让我们创建一个测试用例来测试@PostMapping

@Test 
public void givenUrl_whenPostRequest_thenFindPostResponse() 
  throws Exception {
    
    MockHttpServletRequestBuilder builder = MockMvcRequestBuilders
      .post("/post");
    
    ResultMatcher contentMatcher = MockMvcResultMatchers.content()
      .string("POST Response");
    
    this.mockMvc.perform(builder).andExpect(contentMatcher)
      .andExpect(MockMvcResultMatchers.status().isOk());
    
}

同样,我们为所有HTTP方法创建了剩余的测试用例。

或者,我们始终可以使用任何通用的REST客户端,如PostMan、RESTClient等来测试我们的应用。在这种情况下,我们在使用REST客户端时需要小心选择正确的HTTP方法类型,否则会收到405错误状态。

6. 总结

在这篇文章中,我们快速介绍了使用传统Spring MVC框架进行快速Web开发时的不同@RequestMapping快捷方式。我们可以利用这些快捷方式创建一个干净的代码库。

一如既往,您可以在GitHub项目中找到本教程的源代码。