我用Java编写REST api并使用Groovy和Spock进行测试。
我的控制器中的方法:
@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);
}
我在Spock的测试:
@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路径映射的模糊处理程序方法&#39; http://localhost:35287/endpoint/SomeName1&#39;:{public org.springframework.http.ResponseEntity ExampleController.findByName(java.lang.String), public org.springframework.http.ResponseEntity ExampleController.findById(java.lang.Long)}
答案 0 :(得分:1)
Spring无法区分&#34; / {id}&#34;和&#34; / {name}&#34;。这真的很模糊,因为即使name是一个String而id是一个数字,名称也可以是&#34; 43&#34;太。所以当你打电话给&#34; / 43&#34;它可以解释为一个名称(字符串&#34; 43&#34;),也可以解释为长(43)。
您可以使用以下内容:
true
答案 1 :(得分: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);
}
}