当在 Feign 接口方法中使用 @QueryMap 注解时,Feign 会检查被注解的参数对象的属性。通过反射机制获取对象属性的名称和值,然后将这些属性转换为对应的 URL 查询参数。
例如,假设你有一个名为 UserQuery 的类,包含 name 和 age 两个属性,并且在 Feign 接口方法中有一个 @QueryMap UserQuery query 这样的参数。Feign 会将 query.name 和 query.age 的值分别作为name 和 age 查询参数添加到 URL 中,如 getUser?name=query.name&age=query.age。
Spring Cloud OpenFeign 提供了一个等价的 @SpringQueryMap 注解,用于将 POJO 或 Map 参数注解为查询参数 map。
@SpringQueryMap 是 Spring Cloud OpenFeign 提供的一个注解。它基于 Feign 的 @QueryMap 注解进行了扩展,主要用于在 Spring 应用程序中更方便地处理将 Java 对象转换为 URL 查询参数的场景。这个注解充分利用了 Spring 的配置和功能,使得在构建基于 Feign 的 HTTP 客户端时,能够更好地处理查询参数相关的操作。
与 @QueryMap 的区别:
功能增强:@SpringQueryMap 在 @QueryMap 的基础上增加了更多 Spring 相关的功能。@QueryMap 主要是 Feign 原生的功能,侧重于简单地将对象属性转换为查询参数。而 @SpringQueryMap 能够利用 Spring 的配置和机制,如类型转换、格式化等,提供更加灵活和强大的查询参数处理能力。
配置依赖:@SpringQueryMap 依赖于 Spring Cloud OpenFeign 的配置。它需要在 Spring Cloud 的环境下使用,并且可以通过 Spring Cloud 的配置文件或配置类进行更多的定制化。而 @QueryMap 相对来说更加独立,主要基于 Feign 本身的功能,对 Spring 的依赖较少。
例如,SpringQueryMapObj 类定义了参数 name 和 age:
package com.hxstrive.demo_springcloud_openfeign.entity; import lombok.Builder; import lombok.Data; /** * SpringQueryMap 对象 * @author HuangXin * @since 1.0.0 2024/11/11 11:46 */ @Data @Builder public class SpringQueryMapObj { private String name; private int age; }
定义 Feign 客户端,使用 @SpringQueryMap 注解定义参数:
@GetMapping(path = "/hello") String demo2(@SpringQueryMap SpringQueryMapObj map); @GetMapping(path = "/hello") String demo3(@SpringQueryMap Map<String,String> map);
调用 Feign 客户端:
@GetMapping("/advanced/demo2") public String demo2() { return advancedFeign.demo2(SpringQueryMapObj.builder().name("Bill").age(40).build()); } @GetMapping("/advanced/demo3") public String demo3() { Map<String,String> map = new HashMap<>(); map.put("name", "Bill"); map.put("age", "40"); return advancedFeign.demo3(map); }
输出日志如下:
[AdvancedFeign#demo2] ---> GET http://SERVICE-DEMO/simple/hello?name=Bill&age=40 HTTP/1.1 [AdvancedFeign#demo2] ---> END HTTP (0-byte body) [AdvancedFeign#demo2] <--- HTTP/1.1 200 (112ms) [AdvancedFeign#demo2] connection: keep-alive [AdvancedFeign#demo2] content-length: 11 [AdvancedFeign#demo2] content-type: text/plain;charset=UTF-8 [AdvancedFeign#demo2] date: Mon, 11 Nov 2024 03:50:34 GMT [AdvancedFeign#demo2] keep-alive: timeout=60 [AdvancedFeign#demo2] [AdvancedFeign#demo2] Hello World [AdvancedFeign#demo2] <--- END HTTP (11-byte body)
如果你需要对生成的查询参数 Map 有更多控制,你可以实现一个自定义的 QueryMapEncoder Bean。