带有 List 参数的 Spring Cloud Feign Client @RequestParam 创建错误的请求
Posted
技术标签:
【中文标题】带有 List 参数的 Spring Cloud Feign Client @RequestParam 创建错误的请求【英文标题】:Spring Cloud Feign Client @RequestParam with List parameter creates a wrong request 【发布时间】:2017-06-04 07:32:52 【问题描述】:我有一个 Spring Clound Feign Client 映射定义如下
@RequestMapping(method = RequestMethod.GET, value = "/search/findByIdIn")
Resources<MyClass> get(@RequestParam("ids") List<Long> ids);
当我打电话时
feignClient.get(Arrays.asList(1L,2L,3L))
根据我在调试器中看到的,feign-core 库形成以下请求:
/search/findByIdIn?ids=1&ids=2&ids=3
而不是预期
/search/findByIdIn?ids=1,2,3
这对于以与我的 Feign 客户端方法相同的方式声明的服务器 Spring Data REST 端点是正确的。
因此,由于这个问题,请求总是返回空集。
我看到过类似的 question,但看起来 Feign 客户端在 2015 年就像我预期的那样工作。
我正在使用:
spring-cloud-starter-feign 版本 1.2.4.RELEASE feign-httpclient 9.4.0 版 feign-core 版本 9.4.0有没有办法纠正这种行为并将 Spring Cloud Feign Client 与 Spring Data REST 定义的端点“结合”?
【问题讨论】:
这可能会影响github.com/spring-cloud/spring-cloud-netflix/issues/1526。你可以试试 Dalston.SNAPSHOT,它引入了 spring-cloud-netflix 1.3.0.BUILD-SNAPSHOT。如果没有,你应该打开一个问题。 @spencergibb 确实是这样的行为:github.com/spring-cloud/spring-cloud-netflix/issues/1634 另请参阅示例项目:github.com/abinet/demo 【参考方案1】:我有同样的问题,参数多次出现,而不是预期的逗号分隔的项目序列。解决方案非常简单:
在我的 feign 客户端中,我使用了数组
feignClient.get(new Long[]1L,2L,3L)
而不是集合/列表:
feignClient.get(Arrays.asList(1L,2L,3L))
【讨论】:
【参考方案2】:在 Feign 中,您可以使用以下内容注释您的控制器
@CollectionFormat(feign.CollectionFormat.CSV)
它将处理集合
CSV 格式 findByIdIn?ids=1&ids=2&ids=3
【讨论】:
【参考方案3】:我今天刚刚解决了这个问题,对我来说解决方案非常简单。
如果使用括号[]
表示查询数组:
Resources<MyClass> get(@RequestParam("ids[]") List<Long> ids);
它将创建一个看起来像这样的请求
/search/findByIdIn?ids[]=1&ids[]=2&ids[]=3
大多数服务器端框架会将其解释为数组。 如果您的服务器也在春季,那么您可以像这样选择它
@GetMapping("/search/findByIdIn")
public ResponseEntity findByIdIn(@RequestParam("ids[]") List<Long> ids) ...
请记住,查询必须被编码,[]
被编码为 %5B%5D
。
【讨论】:
【参考方案4】:感谢 @prola 的回答。
只是添加一个显式示例,@CollectionFormat(feign.CollectionFormat.CSV)
注释针对一个方法;你不能全局应用到你的 Feign Client 界面。
所以每个方法都类似于:
@RequestMapping(value = ["/objects"], method = [RequestMethod.GET])
@CollectionFormat(feign.CollectionFormat.CSV)
fun findById(
@RequestParam(value = "object.id", required = true) id: String,
@RequestParam(value = "object.fields", required = false) objectFields: List<String> = DEFAULT_FIELDS_LIST,
@RequestParam(value = "format") format: String = FORMAT,
): ResponseEntity<ObjectsDTO>
结果是
/objects?object.fields=size,weight,location
而不是
/objects?object.fields=size&object.fields=weight&object.fields=location
也可以参考:
1.16.Feign CollectionFormat support OpenFeign #542: Support Multiple Collection Formats【讨论】:
以上是关于带有 List 参数的 Spring Cloud Feign Client @RequestParam 创建错误的请求的主要内容,如果未能解决你的问题,请参考以下文章
Spring Cloud Netflix:通过 RequestInterceptor 将主机请求参数传递给 FeignClient
Spring Cloud Vault 和带有 Vault 后端的 Spring Cloud Config 之间的区别
带有 OpenTracing 的 Spring Cloud Sleuth
带有spring-cloud的Spring Boot:gradle构建失败
如何在 spring-cloud-gateway 合约测试中从 spring-cloud-contract 中设置带有 StubRunner 端口的 url