2017-06-14 53 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); 
    } 
}