正文参数不能与表单参数一起使用-带有Headers和json数据的Feign客户端
Posted
技术标签:
【中文标题】正文参数不能与表单参数一起使用-带有Headers和json数据的Feign客户端【英文标题】:Body parameters cannot be used with form parameters - Feign client with Headers and json data 【发布时间】:2017-09-21 12:44:33 【问题描述】:我有一个这样的 FeignClient
@RequestLine("POST /enroll")
@Headers( "header1: header1", "header2: header2", "Content-Type: application/json" )
ResponseDto enroll(@Param("header1") String header1,@Param("header1") String header1, RequestDto requestDto)throws MyCustomException;
` 我没有使用 Spring Cloud Netflix。但我不断收到以下异常。
Caused by: java.lang.IllegalStateException: Body parameters cannot be used with form parameters.
at feign.Util.checkState(Util.java:128)
at feign.Contract$BaseContract.parseAndValidateMetadata(Contract.java:112)
at feign.Contract$BaseContract.parseAndValidatateMetadata(Contract.java:64)
at feign.ReflectiveFeign$ParseHandlersByName.apply(ReflectiveFeign.java:146)
at feign.ReflectiveFeign.newInstance(ReflectiveFeign.java:53)
at feign.Feign$Builder.target(Feign.java:209)
at feign.Feign$Builder.target(Feign.java:205)
我正在像这样实例化我的客户端。
return Feign.builder()
.encoder(new JacksonEncoder())
.decoder(new JacksonDecoder())
.logger(new Slf4jLogger())
.logLevel(Logger.Level.FULL)
.target(RegularFeignClient.class, url);
【问题讨论】:
【参考方案1】:哇,这是一个棘手的问题。参数的顺序在这里很重要。
@RequestLine("POST /enroll")
@Headers( "header1: header1", "header2: header2", "Content-Type: application/json" )
ResponseDto enroll(RequestDto requestDto, @Param("header1") String header1,@Param("header1") String header1)throws MyCustomException;
这行得通!!!
感谢我的高级开发人员。他找到了。
【讨论】:
所以你把RequestDto requestDto
从最后一个参数移到了第一个参数,这样就成功了?
嗯,奇怪的是,改变参数的顺序也对我有用。就我而言,没有其他答案中提到的问题,所以我尝试了这个技巧(将请求主体对象作为第一个参数)并开始工作。还在挖掘中,如果找到其他原因,我会发布。
我认为这与这个问题有关github.com/OpenFeign/feign/issues/561,我认为他们在较新的版本中已修复,但似乎没有。【参考方案2】:
feign 中的参数顺序不应该像 spencergibb 在本期中所说的那样:https://github.com/spring-cloud/spring-cloud-netflix/issues/1915。如果您不将表单参数与正文参数一起使用,您应该搜索为什么您的参数之一被解释为表单参数。
我的具体问题是,使用 spring @RequestMapping 注释时,feign 错误解释了我的一个参数注释,因为一个错字,在我的情况下,我提供了一个请求路径值 /path/pathParam 并使用 @PathVariable( "pathparam") 小写拼写错误。
【讨论】:
【参考方案3】:我有同样的错误,但不是因为参数的顺序。经调查发现问题出在我大摇大摆的定义中。我已经定义了路径中缺少的参数定义。即:
/someapi/bla/parm1/bla/
parameters:
- $ref: '#/parameters/parm1'
- $ref: '#/parameters/parm2'
改为:
/someapi/bla/parm1/bla/
parameters:
- $ref: '#/parameters/parm1'
解决了这个问题。希望对遇到同样问题的人有所帮助。
【讨论】:
【参考方案4】:如果还有人像我一样来这里,还有另一种可能的情况。 在使用查询参数和请求正文定义路径参数时,我遇到了同样的异常,如下所示:
@RequestLine("POST /namespaces/namespace/releases/release")
Response createRelease(ReleaseBody releaseBody,
@Param("namespace") String namespace,
@Param("release") String release,
@Param("plan") String planName);
即使在更新到最新的 feign
之后,我也收到了异常 IllegalStateException: Body parameters cannot be used with form parameters.
。
在请求行中明确定义查询参数有帮助:
@RequestLine("POST /namespaces/namespace/releases/release?plan=plan")
Response createRelease(ReleaseBody releaseBody,
@Param("namespace") String namespace,
@Param("release") String release,
@Param("plan") String planName);
【讨论】:
以上是关于正文参数不能与表单参数一起使用-带有Headers和json数据的Feign客户端的主要内容,如果未能解决你的问题,请参考以下文章
如何发送带有 URL 参数和 JSON 正文的 POST? [关闭]
将 Swagger 与 Django Rest Framework 一起使用,我可以在不同字段而不是一个正文中看到 POST 参数吗