Feign 调用为何POST不支持同时传入多个SpringQueryMap对象,但是GET方法就支持?

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.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 ,
    );
}
相关推荐
珍珠是蚌的眼泪16 天前
微服务_入门2
网关·微服务·gateway·远程调用·feign
一叶飘零_sweeeet16 天前
为什么 Feign 要用 HTTP 而不是 RPC?
java·网络协议·http·spring cloud·rpc·feign
Xiu Yan1 个月前
负载均衡 Ribbon 与 Fegin 远程调用原理
运维·spring cloud·ribbon·负载均衡·feign
OceanSky61 个月前
Spring Cloud OpenFeign 4组件
openfeign·feign
码农爱java1 个月前
Spring Cloud Open Feign 超时配置及源码分析
spring cloud·微服务·源码·远程调用·feign·open feign
麻辣香蝈蝈1 个月前
【Java】从零到一使用Feign与Sentinel (详细图解)
java·开发语言·spring cloud·nacos·sentinel·feign
自律即自由-2 个月前
【技术积累】如何处理Feign的超时问题
java·spring cloud·feign
cugzyc2 个月前
Feign
feign
-无-为-2 个月前
科普文:微服务之Spring Cloud 服务调用组件Openfeign
spring cloud·微服务·架构·openfeign·feign·服务调用
新时代农民工~2 个月前
SpringCloud之feign
spring cloud·nacos·feign