【发布时间】:2019-10-14 16:34:19
【问题描述】:
我们的一个外部 API 使用带有特殊字符的查询参数名称(不要问我为什么,我不知道)。我的这个 API 的 feign 客户端的方法是这样声明的:
@GetMapping("/v1/user/{userId}/orders")
List<Order> getOrders(
@PathVariable("userId") String userId,
@RequestParam("page[number]") Integer pageNumber,
@RequestParam("page[size]") Integer pageSize);
正如我所提到的,请求参数包含特殊字符 [ 和 ]。
我正在使用 Spock 进行测试,我想像这样设置 Wiremock 存根:
wiremock.stubFor(
get(urlPathMatching('/v1/users/' + userId + '/orders'))
.withQueryParam("page[number]", new EqualToPattern("1"))
.withQueryParam("page[size]", new AnythingPattern())
.willReturn(
status(200)
.withHeader("Content-type", "application/json")
.withBody("""[]""")
))
但我明白了:
--------------------------------------------------------------------------------------------------
| Closest stub | Request |
--------------------------------------------------------------------------------------------------
|
GET | GET
/v1/users/123/orders | /v1/users/123/orders?page%5Bnumber%5D=%7Bpage%5Bnumber%5
| D%7D&page%5Bsize%5D=%7Bpage%5Bsize%5D%7D
|
Query: page[number] = 1 | <<<<< Query is not present
Query: page[size] [anything] (always) | <<<<< Query is not present
|
--------------------------------------------------------------------------------------------------
经过大量试验和错误,我想出了一个解决方案,在 feign 客户端方法中使用 @PathVariables 而不是 @RequestParams:
@GetMapping("/v1/users/{userId}/orders?page[number]={pageNumber}&page[size]={pageSize}")
List<Order> getOrders(
@PathVariable("userId") String userId,
@PathVariable("pageNumber") Integer pageNumber,
@PathVariable("pageSize") Integer pageSize);
并在 Wiremock 中编码所有查询参数
wiremock.stubFor(
get(urlPathMatching('/v1/users/' + userId + '/orders'))
.withQueryParam("page%5Bnumber%5D", new EqualToPattern("1"))
.withQueryParam("page%5Bsize%5D", new AnythingPattern())
.willReturn(
status(200)
.withHeader("Content-type", "application/json")
.withBody("""[]""")
))
然后就可以了。但它看起来像是一种黑客行为。使用可选的查询参数也是有问题的。
有没有办法将@RequestParams 与特殊字符一起使用?
它看起来像 Spring 中的错误?
同时我会尝试调试它以了解问题出在哪里。
【问题讨论】:
标签: spring query-parameters wiremock feign