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

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

    • 1.1 问题背景
    • 1.2 原因分析
    • 1.3 修复方案
      • 1.3.1 修复方案一 切换使用GET方法,可以试用多个`@SpringQueryMap`注解 (测试实际不行)
      • 1.3.2 修复方案二 使用POST方法并将两个参数合并后使用`@RequestBody`注解(未测试)
      • 1.3.3 修复方案二 使用POST方法并将两个参数合并后使用`@SpringQueryMap`注解(亲测可行)

1.1 问题背景

我们知道,在Feign接口中不支持@ModelAttribute 注解,可以试用@SpringQueryMap代替。

由于GET 请求参数的限制,因此,在某些情况会把查询接口使用POST方法。

但是当使用Feign接口调用POST方法,有多个对象参数的时候,如果这样使用会出现问题,第二个参数接受时候会为空。

/**
 * 异地查询日志服务
 */
@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注解 (测试实际不行)

  • 支持,两个参数都可以正确获取到
/**
 * 异地查询日志服务
 */
@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注解(未测试)

/**
 * 异地查询日志服务
 */
@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注解(亲测可行)

/**
 * 异地查询日志服务
 */
@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 ,
    );
}

你可能感兴趣的:(#,极客百科-十万个为什么?,研发踩坑录,Feign,SpringQueryMap,RequestBody,Feign多个对象参数传参,Feign的GET与POST,Feign踩坑)