2017-06-14 14 views
0

我在Java中编写REST API并使用Groovy和Spock进行测试。Groovy - Ambigous处理程序方法

方法在我的控制器:

@GetMapping(value = "/{id}") 
    public ResponseEntity<ExampleObj> findById(@PathVariable Long id) { 
     final ExampleObj dto = service.findById(id); 
     if (dto != null) { 
      return new ResponseEntity<ExampleObj>(dto, HttpStatus.OK); 
     } 
     return new ResponseEntity<ExampleObj>(dto, HttpStatus.NOT_FOUND); 
    } 

@GetMapping(value = "/{name}") 
public ResponseEntity<ExampleObj> findByName(@PathVariable String name) { 
    final ExampleObj dto = service.findByName(name); 
    if (dto != null) { 
     return new ResponseEntity<ExampleObj>(dto, HttpStatus.OK); 
    } 
    return new ResponseEntity<ExampleObj>(dto, HttpStatus.NOT_FOUND); 
} 

和我的斯波克测试:

@Unroll 
    'findByName test'() { 
     when: 
      def response = restTemplate.getForEntity(url, ExampleObj) 
     then: 
      response.getStatusCode() == statusCode 
     where: 
      url         | statusCode 
      '/endpoint/SomeName1'   | HttpStatus.OK 
      '/endpoint/NotExistingName' | HttpStatus.NOT_FOUND 

    } 

@Unroll 
    'findById test'() { 
     when: 
      def response = restTemplate.getForEntity(url, ExampleObj) 
     then: 
      response.getStatusCode() == statusCode 
     where: 
      url     | statusCode 
      '/endpoint/1' | HttpStatus.OK 
      '/endpoint/2' | HttpStatus.NOT_FOUND 

    } 

当我运行测试,我得到以下异常:

java.lang.IllegalStateException:为HTTP路径'http://localhost:35287/endpoint/SomeName1'映射的模糊处理程序方法:{public org.springframework.http.ResponseEntity ExampleController.findByName(java.lang.String),public org。 springframework.http.ResponseEntity ExampleController.findById(java.lang.Long)}

+1

它只是不能决定调用哪个方法,因为这两个连接到相同的路径'/' – daggett

+0

对不起,我编辑的问题 – user

+0

没有。问题出现在@GetMapping(value =“/ {id}”)和'@GetMapping(value =“/ {name}”)'。这些网址没有区别。例如:'/ 111' - 映射应该如何识别要调用'/ {id}'还是'/ {name}'? – daggett

回答

1

Spring无法区分“/ {id}”和“/ {name}”。它确实是不明确的,因为即使名称是字符串,ID是数字,名称也可以是“43”的形式。所以当你调用“/ 43”时,它可以被解释为一个名字(字符串“43”),也可以被解释为一个长形(43)。

,您可以改用类似:

@GetMapping(value = "/") 
public ResponseEntity<ExampleObj> findByName(@RequestParam("name") String name) { 
... 
1

正如其他人所说,你需要以某种方式区分的URL。例如

@GetMapping(value = "/id/{id}") 
public ResponseEntity<ExampleObj> findById(@PathVariable Long id) { ... } 

@GetMapping(value = "/name/{name}") 
public ResponseEntity<ExampleObj> findByName(@PathVariable String name) { ... } 

或者你可以做路由你自己。例如:

@GetMapping(value = "/{value}") 
public ResponseEntity<ExampleObj> find(@PathVariable String value) { 
    try { 
     long id = Long.parseLong(value); 
     return findById(id); 
    } catch (NumberFormatException e) { 
     return findByName(value); 
    } 
} 
相关问题