Spring @RequestMapping注解

x33g5p2x  于2022-09-25 转载在 Spring  
字(8.9k)|赞(0)|评价(0)|浏览(286)

概述

@RequestMapping 是 Spring Web 应用程序中最常用的注解之一。此注解将 HTTP 请求映射到 MVC 和 REST 控制器的处理程序方法。

在这篇文章中,您将看到 @RequestMapping 注解在用于映射 Spring MVC 控制器方法时的通用性。

@RequestMapping基础

在 Spring MVC 应用程序中,RequestDispatcher(下面的前端控制器)servlet 负责将传入的 HTTP 请求路由到控制器的处理程序方法。

在配置 Spring MVC 时,需要指定请求和处理程序方法之间的映射。

要配置 Web 请求的映射,请使用 @RequestMapping 注解。

@RequestMapping 注解可以应用于控制器中的类级别和/或方法级别。

类级注解将特定的请求路径或模式映射到控制器上。然后,您可以应用其他方法级别的注解来使映射更具体到处理程序方法。

这是一个应用于类和方法的 @RequestMapping 注解示例。

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping("/")
    String get() {
        //mapped to hostname:port/home/
        return "Hello from get";
    }
    @RequestMapping("/index")
    String index() {
        //mapped to hostname:port/home/index/
        return "Hello from index";
    }
}

使用前面的代码,对 /home 的请求将由 get() 处理,而对 /home/index 的请求将由 index() 处理。

@RequestMapping 使用多个 URI

一个方法可以有多个请求映射。为此,添加一个带有值列表的 @RequestMapping 注解。

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping(value = {
        "",
        "/page",
        "page*",
        "view/*,**/msg"
    })
    String indexMultipleMapping() {
        return "Hello from index multiple mapping.";
    }
}

正如您在这段代码中看到的,@RequestMapping 支持通配符和 ant 样式的路径。对于前面的代码,所有这些 URL 都将由 indexMultipleMapping() 处理。

  • 本地主机:8080/home
  • 本地主机:8080/home/
  • 本地主机:8080/home/page
  • 本地主机:8080/home/pageabc
  • 本地主机:8080/home/view/
  • 本地主机:8080/home/view/view

@RequestMapping 与 @RequestParam

@RequestParam 注解与 @RequestMapping 一起使用,将 Web 请求参数绑定到处理程序方法的参数。

@RequestParam 注解可以带或不带值使用。该值指定需要映射到处理程序方法参数的请求参数,如此代码片段所示。

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping(value = "/id")
    String getIdByValue(@RequestParam("id") String personId) {
        System.out.println("ID is " + personId);
        return "Get ID from query string of URL with value element";
    }
    @RequestMapping(value = "/personId")
    String getId(@RequestParam String personId) {
        System.out.println("ID is " + personId);
        return "Get ID from query string of URL without value element";
    }
}

在此代码的第 6 行中,请求参数 id 将映射到 getIdByValue() 处理程序方法的 personId 参数 personId。

如果请求参数和处理程序方法参数名称相同,则可以省略 @RequestParam 的 value 元素,如第 11 行所示。

@RequestParam 的 required 元素定义参数值是否是必需的。

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping(value = "/name")
    String getName(@RequestParam(value = "person", required = false) String personName) {
        return "Required element of request param";
    }
}

在此代码片段中,由于所需的元素被指定为 false,因此将为这两个 URL 调用 getName() 处理程序方法:

  • /home/name?person=xyz
  • /home/name

@RequestParam 的默认值用于在请求参数未提供或为空时提供默认值。

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping(value = "/name")
    String getName(@RequestParam(value = "person", defaultValue = "John") String personName) {
        return "Required element of request param";
    }
}

在此代码中,如果请求中的人员请求参数为空,则 getName() 处理程序方法将接收默认值 John 作为其参数。

将@RequestMapping 与HTTP 方法一起使用

Spring MVC @RequestMapping 注解能够处理 HTTP 请求方法,例如 GET、PUT、POST、DELETE 和 PATCH。

默认情况下,所有请求都假定为 HTTP GET 类型。

为了使用特定的 HTTP 方法定义请求映射,您需要使用方法元素在@RequestMapping 中声明 HTTP 方法,如下所示。

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping(method = RequestMethod.GET)
    String get() {
        return "Hello from get";
    }
    @RequestMapping(method = RequestMethod.DELETE)
    String delete() {
        return "Hello from delete";
    }
    @RequestMapping(method = RequestMethod.POST)
    String post() {
        return "Hello from post";
    }
    @RequestMapping(method = RequestMethod.PUT)
    String put() {
        return "Hello from put";
    }
    @RequestMapping(method = RequestMethod.PATCH)
    String patch() {
        return "Hello from patch";
    }
}

在上面的代码片段中,@RequestMapping 注解的方法元素指示了 HTTP 请求的 HTTP 方法类型。

所有处理程序方法都将处理来自同一 URL ( /home) 的请求,但取决于所使用的 HTTP 方法。

例如,对 /home 的 POST 请求将由 post() 方法处理。而对/home 的 DELETE 请求将由 delete() 方法处理。

您可以看到 Spring MVC 如何使用相同的逻辑映射其他方法。

将 @RequestMapping 与 Producible 和 Consumable 一起使用

可以使用 @RequestMapping 注解的生产和消费元素来缩小请求映射类型。

为了以请求的媒体类型生成对象,您可以结合使用@RequestMapping 的produces 元素和@ResponseBody 注解。

您还可以使用@RequestMapping 的consume 元素结合@RequestBody 注解来使用请求的媒体类型的对象。

与@RequestMapping 一起使用可生产和可消费的代码是这样的。

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping(value = "/prod", produces = {
        "application/JSON"
    })
    @ResponseBody
    String getProduces() {
        return "Produces attribute";
    }
    @RequestMapping(value = "/cons", consumes = {
        "application/JSON",
        "application/XML"
    })
    String getConsumes() {
        return "Consumes attribute";
    }
}

在此代码中,getProduces() 处理程序方法生成 JSON 响应。 getConsumes() 处理程序方法使用 JSON 以及请求中存在的 XML。

@RequestMapping 与Headers

@RequestMapping 注解提供了一个标头元素,以根据请求中存在的标头缩小请求映射。

您可以将标题元素指定为 myHeader = myValue。

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping(value = "/head", headers = {
        "content-type=text/plain"
    })
    String post() {
        return "Mapping applied along with headers";
    }
}

在上面的代码片段中,@RequestMapping 注解的 headers 属性缩小了对 post() 方法的映射。这样, post() 方法将处理对 /home/head 的请求,其 content-typeheader 将纯文本指定为值。

您还可以像这样指示多个标头值:

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping(value = "/head", headers = {
        "content-type=text/plain",
        "content-type=text/html"
    }) String post() {
        return "Mapping applied along with headers";
    }
}

这意味着 text/plain 和 text/html 都被 post() 处理程序方法接受。

@RequestMapping 带有请求参数

@RequestMapping 注解的 params 元素进一步帮助缩小请求映射的范围。使用 params 元素,您可以使用多个处理程序方法处理对同一 URL 的请求,但参数不同。

您可以将参数定义为 myParams = myValue。您还可以使用否定运算符来指定请求中不支持特定参数值。

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping(value = "/fetch", params = {
        "personId=10"
    })
    String getParams(@RequestParam("personId") String id) {
        return "Fetched parameter using params attribute = " + id;
    }
    @RequestMapping(value = "/fetch", params = {
        "personId=20"
    })
    String getParamsDifferent(@RequestParam("personId") String id) {
        return "Fetched parameter using params attribute = " + id;
    }
}

在此代码片段中,getParams() 和 getParamsDifferent() 方法都将处理来自同一 URL (/home/fetch) 的请求,但将根据 params 元素执行。

例如,当 URL 为 /home/fetch?id=10 时,getParams() 处理程序方法将以 id 值 10 执行。对于 URL,localhost:8080/home/fetch?personId=20,getParamsDifferent () 处理程序方法使用 id 值 20 执行。

将@RequestMapping 与动态URI 一起使用

@RequestMapping 注解与@PathVaraible 注解结合使用来处理动态URI。在这个用例中,URI 值可以作为控制器中处理程序方法的参数。您还可以使用正则表达式仅接受与正则表达式匹配的动态 URI 值。

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping(value = "/fetch/{id}", method = RequestMethod.GET)
    String getDynamicUriValue(@PathVariable String id) {
        System.out.println("ID is " + id);
        return "Dynamic URI parameter fetched";
    }
    @RequestMapping(value = "/fetch/{id:[a-z]+}/{name}", method = RequestMethod.GET)
    String getDynamicUriValueRegex(@PathVariable("name") String name) {
        System.out.println("Name is " + name);
        return "Dynamic URI parameter fetched using regex";
    }
}

在这段代码中,getDynamicUriValue() 方法将对 localhost:8080/home/fetch/10 的请求执行。此外,getDynamicUriValue() 处理程序方法的 id 参数将动态填充值 10。

getDynamicUriValueRegex() 方法将对 localhost:8080/home/fetch/category/shirt 的请求执行。但是,对 /home/fetch/10/shirt 的请求将引发异常,因为它与正则表达式不匹配。

@PathVariable 与 @RequestParam 的工作方式不同。您可以使用 @PathVariable 从 URI 中获取查询参数的值。另一方面,您使用 @RequestParam 从 URI 模板中获取参数值。

@RequestMapping 默认处理程序方法

在控制器类中,您可以拥有在请求默认 URI 时执行的默认处理程序方法。

这是默认处理程序方法的示例。

@RestController
@RequestMapping("/home")
public class IndexController {
    @RequestMapping()
    String
    default () {
        return "This is a default method for the class";
    }
}

在此代码中,对 /home 的请求将由 default() 方法处理,因为注解未指定任何值。

@RequestMapping 快捷方式

Spring 4.3 引入了方法级别的变体,也称为 @RequestMapping 的组合注解。组合注解更好地表达了注解方法的语义。它们充当@RequestMapping 的包装器,并已成为定义端点的标准方法。

例如,@GetMapping 是一个组合注解,它充当@RequestMapping(method =RequestMethod.GET) 的快捷方式。
方法级别的变体是:

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

以下代码显示使用组合注解。

@RestController
@RequestMapping("/home")
public class IndexController {
    @GetMapping("/person")
    public @ResponseBody ResponseEntity < String > getPerson() {
        return new ResponseEntity < String > ("Response from GET", HttpStatus.OK);
    }
    @GetMapping("/person/{id}")
    public @ResponseBody ResponseEntity < String > getPersonById(@PathVariable String id) {
        return new ResponseEntity < String > ("Response from GET with id " + id, HttpStatus.OK);
    }
    @PostMapping("/person")
    public @ResponseBody ResponseEntity < String > postPerson() {
        return new ResponseEntity < String > ("Response from POST method", HttpStatus.OK);
    }
    @PutMapping("/person")
    public @ResponseBody ResponseEntity < String > putPerson() {
        return new ResponseEntity < String > ("Response from PUT method", HttpStatus.OK);
    }
    @DeleteMapping("/person")
    public @ResponseBody ResponseEntity < String > deletePerson() {
        return new ResponseEntity < String > ("Response from DELETE method", HttpStatus.OK);
    }
    @PatchMapping("/person")
    public @ResponseBody ResponseEntity < String > patchPerson() {
        return new ResponseEntity < String > ("Response from PATCH method", HttpStatus.OK);
    }
}

在此代码中,每个处理程序方法都使用 @RequestMapping 的组合变体进行注解。尽管每个变体都可以与带有方法属性的@RequestMapping 互换使用,但使用组合变体被认为是最佳实践——主要是因为组合注解减少了应用程序端的配置元数据,并且代码更具可读性。

@RequestMapping 结论

正如您在这篇文章中看到的,@RequestMapping 注解非常通用。您可以使用此注解来配置 Spring MVC 以处理各种用例。它可用于配置传统的网页请求以及 Spring MVC 中的 RESTFul Web 服务。

相关文章