当前位置: 首页 > 知识库问答 >
问题:

Spring Boot OpenFeign:java。lang.IllegalStateException:方法的主体参数太多

文德曜
2023-03-14

下面的示例演示了使用OpenFeign时遇到的问题。当响应对象的字段太多时,问题就会变得明显,这会引发一个错误:方法的参数太多。示例1工作正常,但示例2失败。

示例1使用HTTP. POST与示例2中使用的响应对象相同,后者使用HTTP. GET。

为什么在HTTP. GET方法中OpenFaigns限制字段,并抛出异常?我不能使用HTTP. POST获取/获取/读取资源。糟糕的REST API设计标准。

使用相同的响应对象,对于两个HTTP. POST(工作),HTTP. GET失败

public interface ClientFeignV2 {

//Example 1 
@Headers("Content-Type: application/json") @RequestLine("POST api/v2/clients") ClientResponse findAllClientsByUid1(@RequestBody ClientRequest request);

//Example 2
@Headers("Content-Type: application/json")
@RequestLine("GET api/v2/clients/{uid}")
ClientResponse findAllClientsByUid(@PathVariable(value = "uid") String uid,
                                         @RequestParam(value = "limit", required = false) Integer limit,
                                         @RequestParam(value = "offset", required = false) Integer offset);
}

StackTrace:

Caused by: java.lang.IllegalStateException: Method has too many Body parameters: public abstract com.services.requestresponse.ClientResponse com.microservice.gateway.feign.v2.ClientFeignV2.findAllClientsByUid(java.lang.String,java.lang.Integer,java.lang.Integer)
at feign.Util.checkState(Util.java:128) ~[feign-core-9.4.0.jar:na]
at feign.Contract$BaseContract.parseAndValidateMetadata(Contract.java:114) ~[feign-core-9.4.0.jar:na]
at feign.Contract$BaseContract.parseAndValidatateMetadata(Contract.java:64) ~[feign-core-9.4.0.jar:na]
at feign.ReflectiveFeign$ParseHandlersByName.apply(ReflectiveFeign.java:146) ~[feign-core-9.4.0.jar:na]
at feign.ReflectiveFeign.newInstance(ReflectiveFeign.java:53) ~[feign-core-9.4.0.jar:na]
at feign.Feign$Builder.target(Feign.java:209) ~[feign-core-9.4.0.jar:na]
at feign.Feign$Builder.target(Feign.java:205) ~[feign-core-9.4.0.jar:na]
at com.microservice.gateway.service.v2.impl.ClientServiceV2Impl.<init>(ClientServiceV2Impl.java:27) ~[classes/:na]
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_222]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_222]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_222]
at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_222]
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:203) ~[spring-beans-5.2.3.RELEASE.jar:5.2.3.RELEASE]
... 40 common frames omitted

我看了OpenFaigns留档,它支持上面的实现。如果我找不到这个问题的解决方案,我将不得不求助于一个解决方案,并使用HTTP. POST@刚体,根据REST-API设计标准,这不是一个理想的解决方案。

共有1个答案

贺元明
2023-03-14

根据标签,您使用的是Spring Boot,显然是Spring Cloud OpenFeign。问题是你混合了两份不同的合同。

@ask estLine@Headers这样的注释来自核心模拟库。您可以将其用作声明性HTTP客户端,而不仅仅是在Spring应用程序中(在这种情况下,它不需要使用Spring注释)。

因此,正确的“示例2”可以是这样的:

@Headers("Content-Type: application/json")
@RequestLine("GET api/v2/clients/{uid}?limit={limit}&offset={offset}")
ClientResponse findAllClientsByUid(@Param("uid") String uid,
                                   @Param("limit") Integer limit,
                                   @Param("offset") Integer offset);

另一方面,像@RequestParam@PathVariable这样的东西来自SpringWeb。如果您有Spring Cloud OpenFeign库(顺便说一句,核心feign是它的一个组件),就可以使用它们。这个库提供了对SpringMvcContract的支持,在它的例子中,允许您使用常用的SpringWeb注释来定义请求映射,而不是使用特定于外部的注释。

SpringMvcContract的情况下,“示例2”可能类似于:

@GetMapping(value = "api/v2/clients/{uid}", consumes = MediaType.APPLICATION_JSON_VALUE)
ClientResponse findAllClientsByUid(@PathVariable(value = "uid") String uid,
                @RequestParam(value = "limit", required = false) Integer limit,
                @RequestParam(value = "offset", required = false) Integer offset);

值得一提的是,在Spring Cloud OpenFeign中,默认情况下使用第二种方法。要将其更改回纯假的合同,请定义自定义contractbean(源代码):

@Bean
public Contract feignContract() {
    return new feign.Contract.Default();
}
 类似资料:
  • 我在RestController类中有以下requestMethod,它运行良好: 我还有一个假客户也工作得很好。我在两种方法中都添加了一个名为forceSupplier的新参数,但添加后,我发现,但我真的不明白为什么我会收到此消息,因为参数是相同的。 这是假装的方法: 我做错了什么?谢谢

  • 我创建了模拟客户端来调用我的RestApi。当我尝试运行我的服务,我收到错误从这个请求方法对于@请求身体我只使用对象类型,因为每次我可以发送另一个身体请求。

  • 我正在尝试编写一个服务,它将通过eureka服务器绑定到另一个服务,我想使用FaignClient Hystrix,我无法实现GET控制器,我遇到了以下异常: 这是我的控制器在主服务中的外观: 这就是我的控制器在服务中的样子,在那里我试图实现飞扬客户端: 这是我制作FaignClient的界面 这是FaignClient的后备类: CarFilter: 请帮帮我,我已经被这个任务折磨了很长时间了。

  • 我对Java Spring的ExceptionHandler有一个问题。我有一个名为EntityNotFoundException的异常,我希望在引发异常时从REST控制器调用ExceptionHandler方法。 这是我的REST控制器方法代码: 这是我的异常处理程序代码: } 我不知道为什么,当我获得DataIntegrityViolationException时,会调用ExceptionHa

  • 我有一个简单的POJO: 和一个简单的假冒客户端: 根据拉动请求#667,我期望这被翻译为: 但我得到的是: 请注意,参数在请求主体中传递,而不是作为传递。 它试图调用的endpoint定义为: 我错过了什么?如何使用将其作为查询参数传递?

  • 问题内容: 我刚刚开始用Java编写程序。以下Java代码是什么意思? What is String[] args? When would you use these args? 源代码和/或示例优先于抽象解释 问题答案: 在Java中,包含提供的命令行参数作为对象数组。 换句话说,如果你运行你的程序作为然后将包含。 如果要输出的内容,可以像这样遍历它们…