FeignClient 将 GET 方法转换为 POST

问题描述 投票:0回答:6

我不知道我做错了什么,但每次 feign 客户端都会将声明为 get 的方法转换为 post 类型。

@FeignClient(name = "my-service", url = "http://localhost:8114", path = "service")
public interface MyServiceClient {

    @RequestMapping(method = GET, value = "/clients")
    Client getClients(@QueryMap MyPojo pojo);
}

@Getter
@Setter
public class MyPojo {

    @NotNull
    private String someValue;
    @NotNull
    private SomeEnum someEnum;
}

此设置应解决此请求:

GET http://localhost:8114/service/clients?someValue=foo&someEnum=bar

但是每次我得到这个结果:

{
  "timestamp": 1542378765498,
  "status": 405,
  "error": "Method Not Allowed",
  "exception": "org.springframework.web.HttpRequestMethodNotSupportedException",
  "message": "Request method 'POST' not supported",
  "path": "/service/clients"
}

但是当我这样做时效果很好:

@RequestMapping(method = GET, value = "/clients?someValue=foo&someEnum=bar")
Client getClients();

我正在开发

spring-cloud-starter-feign 1.2.7.RELASE
版本,其中包含
feign-core/sl4fj/hystrix/ 9.3.1
版本,但我也在 10.1.0 版本上对其进行了测试,结果相同。

我应该怎么做才能解决这个问题?

java spring spring-cloud-feign feign
6个回答
4
投票

在我的项目中,我将

spring-cloud-dependencies
Camden.SR7
版本一起使用,其中包含
9.3.1
feign 版本,目前最新版本是
Finchley.RELEASE
,其中包含 feign
9.7
,我看到它专用于
spring-boot 2.x.x
,但我的整个基础设施(配置/尤里卡服务器)运行在
1.5.x
上,因此它会产生下一个问题。我查看了 feign 的 github 文档,发现
@Param
注释可能会有帮助,但是当我在带有 3 个参数的方法中使用它时,它会抛出异常
Method has too many Body parameters~
。最后,来自 spring 的注释
@RequestParam
可以作为解决方法,但我没有找到任何可以组合这些注释的信息来源。

@RequestMapping(method = GET, value = "/clients")
Client getClients(@RequestParam("someValue") String someValue, @RequestParam("someEnum") String someEnum);

我没有找到包含

spring-cloud-dependencies
feign 的
9.7
版本,它专用于
spring-boot 1.5.x
应用程序。


2
投票

我遇到了 Spring 的

@FeignClient
出于不同原因将 GET 请求转换为 POST 的实例。就我而言,调用的 REST API 使用 HTTP 查询参数。调用此 API 的 Feign 客户端方法有一个用
@QueryParam
注释的参数(即 javax.ws.rs.QueryParam)作为此查询参数。 Feign 显然无法识别此注释,因此将该方法参数用作请求正文中的表单 post 参数(并将请求方法转换为 POST),而不是将其用作查询参数。

修复方法是将

javax.ws.rs.QueryParam
注释替换为
org.springframework.web.bind.annotation.RequestParam

此案例使用 spring-cloud-openfeign-core-2.2.5.RELEASE 发生。


1
投票

正如已经讨论过的这里:feign 9.3.1确实支持带有POJO的@QueryMap,您需要使用Map,尝试更新到feign 9.7或10.0.1


1
投票

我遇到了类似的问题,使用 Feign 和 Spring Boot 并使用单个复杂对象作为参数。我成功解决了这个问题,认识到:

  1. 如果@Parameter旁边没有指定@SpringQueryMap,Feign会将参数对象转换为json并将其放入请求体中。
  2. 由于带有body的GET请求并不真正符合http标准,Feign默认使用的http客户端会自动将GET转换为POST。不过,这是可以解决的:如果将 Apache Http 客户端 5 添加为项目的依赖项,Feign 将自动使用它而不是 java.net.http.HttpClient。而Apache的客户端并没有改变方法,所以会保持GET。 (请注意,参数对象仍将以 json 形式在正文中传输。) 只需将其放入您的 pom.xml 即可:
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-hc5</artifactId>
        </dependency>

Spring Boot 的自动配置功能将处理剩下的事情。


0
投票

就我而言,我使用

@Param
将请求参数传递到 GET 端点。我不知道为什么,但显然 Feign 将其转换为 POST 请求。

我解决了我的问题,用

@Param
 替换 
@QueryMap

样品:

@RequestLine("GET")
MyObjResponse findByObjByIdAndNameUsingRequestParams(@QueryMap Map<String, String> queryMap);

现在 Feign 发送正确的 GET http 方法。


0
投票

我也面临这个问题。并在注意到路径值中的参数名称与 @PathVariable 别名中使用的大小写不同后解决了该问题。

@RequestMapping(method = RequestMethod.GET, path = "v1/{key}/user/profiles/{parentUser}")
String getUser(@PathVariable("key") String key, @PathVariable("parentuser") String parentuser);

如果您注意到上面的代码片段。 Path 值中的parentUser 与PathVariable 注释中的名称parentuser 不匹配。

在调用客户端期间,假设 PathVariable 是一个附加参数,并尝试将其转换为 Gson 对象。

如果服务器上的控制器有另一个具有类似 URL 的方法,例如PUT 操作,然后它会尝试调用该方法而不是 GET 方法。

我不确定答案是否相关。但经过长时间的分析,我发现了这个愚蠢的错误,并想这是否可以帮助处于类似情况的其他人,并可以节省不必要的压力和时间。

谢谢

© www.soinside.com 2019 - 2024. All rights reserved.