Feign 调用为何POST不支持同时传入多个SpringQueryMap对象,但是GET方法就支持?
-
- [1.1 问题背景](#1.1 问题背景)
- [1.2 原因分析](#1.2 原因分析)
- [1.3 修复方案](#1.3 修复方案)
-
- [1.3.1 修复方案一 切换使用GET方法,可以试用多个`@SpringQueryMap`注解 (测试实际不行)](#1.3.1 修复方案一 切换使用GET方法,可以试用多个
@SpringQueryMap
注解 (测试实际不行)) - [1.3.2 修复方案二 使用POST方法并将两个参数合并后使用`@RequestBody`注解(未测试)](#1.3.2 修复方案二 使用POST方法并将两个参数合并后使用
@RequestBody
注解(未测试)) - [1.3.3 修复方案二 使用POST方法并将两个参数合并后使用`@SpringQueryMap`注解(亲测可行)](#1.3.3 修复方案二 使用POST方法并将两个参数合并后使用
@SpringQueryMap
注解(亲测可行))
- [1.3.1 修复方案一 切换使用GET方法,可以试用多个`@SpringQueryMap`注解 (测试实际不行)](#1.3.1 修复方案一 切换使用GET方法,可以试用多个
1.1 问题背景
我们知道,在Feign接口中不支持@ModelAttribute
注解,可以试用@SpringQueryMap代替。
由于GET 请求参数的限制,因此,在某些情况会把查询接口使用POST方法。
但是当使用Feign接口调用POST方法,有多个对象参数的时候,如果这样使用会出现问题,第二个参数接受时候会为空。
java
/**
* 异地查询日志服务
*/
@FeignClient(name = "remoteCallElasticsearchService", url = "${query-current-service-provider.prevBaseUrl}")
public interface RemoteCallElasticsearchService {
/**
* 异地调用日志查询服务
* @param elkLogQueryParam 日志查询请求参数
* @param myPageParam 分页参数
* @return 日志查询结果
*/
@PostMapping(value = "/rpc-service/queryRemoteElkLogInfoPageList.do")
Page<ElkLogResponseVO> queryRemoteElkLogInfoPageList(@SpringQueryMap ElkLogQueryParam elkLogQueryParam,
@SpringQueryMap MyPageParam myPageParam
);
}
1.2 原因分析
Feign 调用为何POST不支持同时传入多个SpringQueryMap对象,但是GET方法就支持?
- Feign是一个声明式的HTTP客户端库,通常用于调用RESTful服务。
- 在Feign中,Spring Cloud的
@FeignClient
注解通常用于定义和配置需要调用的目标服务。- Feign的设计是基于HTTP方法和RESTful风格的,因此它在处理HTTP请求时遵循了RESTful的规范。
- 在HTTP中,GET请求通常允许将多个查询参数附加到URL中,因此您可以轻松地使用多个
@SpringQueryMap
对象作为参数。这是因为GET请求的参数是直接附加到URL上的,没有请求体,所以它们可以并存。- 而POST请求通常用于发送复杂的数据,通常使用请求体来传递参数。
- 因此,在Feign中,通过
@RequestBody
或@RequestPart
等注解,您可以将数据作为请求体传递给POST请求。- 但是,Feign的设计不直接支持将多个
@SpringQueryMap
对象传递给POST方法,因为POST请求通常不应该在请求体中包含大量查询参数,而应该将它们包含在请求体中,以进行更复杂的操作。- 如果您需要将多个参数传递给POST方法,通常的做法是将它们合并为一个对象,然后将该对象作为请求体发送,而不是使用多个
@SpringQueryMap
对象。- 这可以提高代码的可读性和维护性,并符合RESTful设计的最佳实践。
- 要传递多个查询参数,可以将它们包装在一个对象中,然后将该对象作为请求体传递给POST方法。
- 例如,您可以创建一个DTO(数据传输对象)来包含所有参数,然后将其传递给Feign的POST方法。
- 在HTTP中,GET请求通常允许将多个查询参数附加到URL中,因此您可以轻松地使用多个
@SpringQueryMap
对象作为参数。这是因为GET请求的参数是直接附加到URL上的,没有请求体,所以它们可以并存。 - Feign的设计不直接支持将多个
@SpringQueryMap
对象传递给POST方法,因为POST请求通常不应该在请求体中包含大量查询参数,而应该将它们包含在请求体RquestBody中,以进行更复杂的操作。
1.3 修复方案
1.3.1 修复方案一 切换使用GET方法,可以试用多个@SpringQueryMap
注解 (测试实际不行)
- 支持,两个参数都可以正确获取到
java
/**
* 异地查询日志服务
*/
@FeignClient(name = "remoteCallElasticsearchService", url = "${query-current-service-provider.prevBaseUrl}")
public interface RemoteCallElasticsearchService {
/**
* 异地调用日志查询服务
* @param elkLogQueryParam 日志查询请求参数
* @param myPageParam 分页参数
* @return 日志查询结果
*/
@GetMapping(value = "/rpc-service/queryRemoteElkLogInfoPageList.do")
Page<ElkLogResponseVO> queryRemoteElkLogInfoPageList(@SpringQueryMap ElkLogQueryParam elkLogQueryParam,
@SpringQueryMap MyPageParam myPageParam
);
}
1.3.2 修复方案二 使用POST方法并将两个参数合并后使用@RequestBody
注解(未测试)
java
/**
* 异地查询日志服务
*/
@FeignClient(name = "remoteCallElasticsearchService", url = "${query-current-service-provider.prevBaseUrl}")
public interface RemoteCallElasticsearchService {
/**
* 异地调用日志查询服务
* @param elkLogQueryParam 日志查询请求参数
* @param myPageParam 分页参数
* @return 日志查询结果
*/
@PostMapping(value = "/rpc-service/queryRemoteElkLogInfoPageList.do")
Page<ElkLogResponseVO> queryRemoteElkLogInfoPageList(@RequestBody ElkLogQueryWithPageParam elkLogQueryWithPageParam ,
);
}
1.3.3 修复方案二 使用POST方法并将两个参数合并后使用@SpringQueryMap
注解(亲测可行)
java
/**
* 异地查询日志服务
*/
@FeignClient(name = "remoteCallElasticsearchService", url = "${query-current-service-provider.prevBaseUrl}")
public interface RemoteCallElasticsearchService {
/**
* 异地调用日志查询服务
* @param elkLogQueryParam 日志查询请求参数
* @param myPageParam 分页参数
* @return 日志查询结果
*/
@PostMapping(value = "/rpc-service/queryRemoteElkLogInfoPageList.do")
Page<ElkLogResponseVO> queryRemoteElkLogInfoPageList(@SpringQueryMap ElkLogQueryWithPageParam elkLogQueryWithPageParam ,
);
}