使用Spring处理在REST应用程序中映射的模糊处理程序方法

时间:2016-02-02 14:19:28

标签: spring rest path-variables request-mapping

我尝试使用以下代码:

@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public Brand getBrand(@PathVariable Integer id) {
    return brandService.getOne(id);
}

@RequestMapping(value = "/{name}", method = RequestMethod.GET)
public List<Brand> getBrand(@PathVariable String name) {
    return brandService.getSome(name);
}

但我得到这样的错误,我该怎么办?

java.lang.IllegalStateException: Ambiguous handler methods mapped for HTTP path 'http://localhost:8080/api/brand/1': {public java.util.List com.zangland.controller.BrandController.getBrand(java.lang.String), public com.zangland.entity.Brand com.zangland.controller.BrandController.getBrand(java.lang.Integer)}
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:375) ~[spring-webmvc-4.2.4.RELEASE.jar:4.2.4.RELEASE]

2 个答案:

答案 0 :(得分:18)

Spring无法区分请求GET http://localhost:8080/api/brand/1是由getBrand(Integer)还是由getBrand(String)处理,因为您的映射不明确。

尝试使用getBrand(String)方法的查询参数。这似乎更合适,因为您正在执行查询:

@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public Brand getBrand(@PathVariable Integer id) {
    return brandService.getOne(id);
}

@RequestMapping(method = RequestMethod.GET)
public List<Brand> getBrand(@RequestParam(value="name") String name) {
    return brandService.getSome(name);
}

使用上述方法:

  • GET http://localhost:8080/api/brand/1等请求将由getBrand(Integer)处理。
  • GET http://localhost:8080/api/brand?name=nike等请求将由getBrand(String)处理。

只是一个提示

作为一种良好做法,请始终使用复数名词作为资源。而不是/brand,请使用/brands

答案 1 :(得分:0)

@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public Brand getBrand(@PathVariable Integer id) {
    return brandService.getOne(id);
}

@RequestMapping(value = "/{name}", method = RequestMethod.GET)
public List<Brand> getBrand(@PathVariable String name) {
    return brandService.getSome(name);
}

运行该应用程序并访问您尝试进行编码的端点时,您会意识到以下内容:“ {http://localhost:8086/brand/1”和“ http://localhost:8086/brand/FooBar”对应于相同的URL格式(可以称为协议) +端点+“品牌” +)。因此,如果SpringBoot应该使用String数据类型或Integer调用函数“ getBrand”,则本质上会感到困惑。因此,要克服这一点,我建议您使用@cassiomolin提到的查询参数,或者为两个调用使用单独的路径。这可能违反REST原则,但是假设您只是在做一个示例应用程序,这是另一种解决方法。

@RequestMapping(value = "/id/{id}", method = RequestMethod.GET)
public Brand getBrand(@PathVariable Integer id) {
    return brandService.getOne(id);
}

@RequestMapping(value = "/name/{name}", method = RequestMethod.GET)
public List<Brand> getBrand(@PathVariable String name) {
    return brandService.getSome(name);
}

这对我有用。