Spring Cloud OpenFeign @SpringQueryMap |
您所在的位置:网站首页 › getmapping注解的解析 › Spring Cloud OpenFeign @SpringQueryMap |
@SpringQueryMap
@SpringQueryMap 注解是 spring-cloud-openfeign-core:2.1.0.RELEASE 开始引入的一个新注解 它被包含在 spring-cloud-starter-openfeign:2.1.0.RELEASE 中 org.springframework.cloud spring-cloud-starter-openfeign 2.1.0.RELEASE虽然 OpenFeign 的 @QueryMap注解支持将 POJO 映射到 GET 方法的参数上。但由于缺少value属性而与 Spring 不兼容,为此 Spring Cloud OpenFeign 提供了等效的@SpringQueryMap注解,用于将 POJO 或 Map ,映射为 GET 方法的参数。 使用@SpringQueryMap 注解用法也很简单,假设有一个叫 StudentDTO的类 public class StudentDTO { private String name; private String age; // get、set 方法 }spring-cloud-openfeign-core:2.1.0.RELEASE 之前,你不能直接传递对象,只能将它手动拆分成多个字段进行传参 @FeignClient("demo") public interface DemoTemplate { @GetMapping(path = "/demo") String demoEndpoint(@RequestParam String name, @RequestParam String age); }spring-cloud-openfeign-core:2.1.0.RELEASE 开始 @SpringQueryMap注解可以自动帮你完成参数映射 // 等效于上面的写法 @FeignClient("demo") public interface DemoTemplate { @GetMapping(path = "/demo") String demoEndpoint(@SpringQueryMap StudentDTO studentDTO); } @SpringQueryMap 注解不解析父类字段这句话是啥意思了? 我们来看一个例子,还是刚刚那个 StudentDTO,但是现在它继承了 PageDTO public class PageDTO { private Integer page; private Integer siez; // get、set 方法 } public class StudentDTO exdents PageDTO { private String name; private String age; // get、set 方法 }然后同样使用 @SpringQueryMap 来映射 @FeignClient("demo") public interface DemoTemplate { @GetMapping(path = "/demo") String demoEndpoint(@SpringQueryMap StudentDTO studentDTO); // 等效于 String demoEndpoint(@RequestParam String name,@RequestParam String age); }但实际结果可能跟你想的不太一样,上面的写法等效于 String demoEndpoint(@RequestParam String name, @RequestParam String age); 可以看到 StudentDTO exdents PageDTO 中的参数并没有映射上去 原因其实,准确来说,“@SpringQueryMap 注解不解析父类字段” 这种说法并不准确,因为这并不是 @SpringQueryMap 的问题 原生的 OpenFeign 在使用原生的 @QueryMap 注解时,也会出现这个问题 问题的重点不在于 @QueryMap 注解而是在于 OpenFeign 的 encode 上 @QueryMap 对应的 encode 为 QueryMapEncoder, 而从 QueryMapEncoder 源码注释中可以看出,FieldQueryMapEncoder 虽然是 QueryMapEncoder 的默认实现,但是已经不推荐使用了,其中一个原因就是因为它不会去映射 POJO 的父类属性 public interface QueryMapEncoder { /** * ... */ Map encode(Object object); /** * @deprecated use {@link BeanQueryMapEncoder} instead. default encoder uses reflection to inspect * provided objects Fields to expand the objects values into a query string. If you * prefer that the query string be built using getter and setter methods, as defined * in the Java Beans API, please use the {@link BeanQueryMapEncoder} */ class Default extends FieldQueryMapEncoder { } } 解决方案知道了原因,解决方案就很简单了,跟换为 @QueryMap 的 QueryMapEncoder 为推荐的 BeanQueryMapEncoder 就行了 @Configuration public class FeignClientCustomizerConfig { /** * 替换解析 queryMap 的类,实现父类中变量的映射 * @return */ @Bean public Feign.Builder feignBuilder() { return Feign.builder() .queryMapEncoder(new BeanQueryMapEncoder()); } }然后使用上面自定义的配置 如果想让它全局生效,就在 Spting boot 启动类上 @EnableFeignClients(defaultConfiguration = FeignClientCustomizerConfig.class) @SpringBootApplication public class TestApplication { public static void main(String[] args) { } }如果只想让它在单个 FeignClient 上生效,就加上 configuration 属性 @FeignClient(value = "xxx", configuration = FeignClientCustomizerConfig.class) @RequestMapping("/xxx") @Service public interface XxxFeignClient { } |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |