为什么@GetMapping和@PostMapping对相同的URI抛出错误?

时间:2020-01-09 07:09:57

标签: spring spring-restcontroller

选项1:工作正常

@RequestMapping(value = "myuri/" ,method = RequestMethod.GET)
 MyResponse myMethod1(@RequestBody MyRequest myRequest) {
   // Code
 }

@RequestMapping(value = "myuri/" ,method = RequestMethod.POST)
 MyResponse myMethod2(@RequestBody MyRequest myRequest) {
   // Code
 }

选项2:不起作用

@GetMapping
@RequestMapping(value = "myuri/" )
MyResponse myMethod1(@RequestBody MyRequest myRequest) {

    return null;
}

@PostMapping
@RequestMapping(value = "myuri/")
MyResponse myMethod2(@RequestBody MyRequest myRequest) {
    return null;
}

为什么选项2引发异常

java.lang.IllegalStateException:含糊的映射。

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'myRestController' method 
com.a.b.c.service.model.MyResponse com.a.b.my.service.rest.myRestController.myMethod2(com.a.b.c.service.model.MyRequest)
to { /my/myuri/}: There is already 'myRestController' bean method
com.a.b.c.service.model.MyResponse com.a.b.my.service.rest.myRestController.myMethod1(com.a.b.c.service.model.MyRequest) mapped.

1 个答案:

答案 0 :(得分:0)

您的第一个示例将2种方法映射到具有不同post方法的单个URL。

  1. @RequestMapping(value = "myuri/" ,method = RequestMethod.GET),这将导致myuri上的GET请求到myMethod1的映射。

  2. @RequestMapping(value = "myuri/" ,method = RequestMethod.POST),这将导致myuri上的POST请求进入myMethod2的映射。

您的第二个示例将2个方法映射到2个使用不同方法和相同方法的URL。

  1. @RequestMapping(value = "myuri/"),这将导致对myuri上的 ANY 请求进行映射,以转到myMethod1
  2. @GetMapping,这将导致/上的GET请求转到myMethod1
  3. @RequestMapping(value = "myuri/"),这将导致对myuri上的 ANY 请求进行映射,以转到myMethod2
  4. @PostMapping,这将导致/上的POST请求转到myMethod1

由于1和3是相同的映射,因此要使用不同的方法,Spring无法区分并抛出错误。

这可能是由于您误解了@GetMapping@PostMapping注释以及如何使用它们的事实。映射是@RequestMapping(method=GET)@RequestMapping(method=POST)的捷径。在定义中为您节省相同的空间,它们非常清楚。

所以不是

@GetMapping
@RequestMapping(value = "myuri/" )

您应该只写@GetMapping("myuri/")即可实现所需的目标。检测到后,这将转换为myuri上的GET请求的映射,以执行给定的方法。