Spring cloud Feign不支持对象传参解决办法[完美解决]

简介: Spring cloud Feign不支持对象传参解决办法[完美解决]spring cloud 使用 Feign 进行服务调用时,不支持对象参数。通常解决方法是,要么把对象每一个参数平行展开,并使用 @RequestParam 标识出每一个参数,要么用 @RequestBody 将请求改为 body 传参,虽然这样解决了问题,但是这样限制了传参方式,并且使代码变得很繁重。

Spring cloud Feign不支持对象传参解决办法[完美解决]

spring cloud 使用 Feign 进行服务调用时,不支持对象参数。

通常解决方法是,要么把对象每一个参数平行展开,并使用 @RequestParam 标识出每一个参数,要么用 @RequestBody 将请求改为 body 传参,虽然这样解决了问题,但是这样限制了传参方式,并且使代码变得很繁重。

以下为完美解决 Feign 对象传参问题的办法。
  1. 引入如下依赖(可以在maven仓库中搜索 strongfeign)

复制代码
1
2
3 com.moonciki.strongfeign
4 feign-httpclient
5 10.2.3
6
复制代码
该源码修改自 https://github.com/OpenFeign/feign,提交过pr,但是项目原作者并没有采纳,pr地址如下:https://github.com/OpenFeign/feign/pull/949

之后为了同步到了maven 仓库,做了相应删减及pom的变更,具体改动可参考github。地址:https://github.com/cdmamata/strong-feign

注意:不要使用 10.3.x版本,该版本有问题。如果jar包无法下载请使用 maven 中央仓库。

  1. 创建如下三个类

    开始时,打算把以下三个类加进仓库中,但由于如下三个类内容不多,并且有很多定制化的可能,因此单独实现。
    
    2.1 ParamModel.java
    

复制代码
1 package com.moonciki.strongfeign.model.annotation;
2
3 import java.lang.annotation.*;
4
5 @Target({ElementType.PARAMETER})
6 @Retention(RetentionPolicy.RUNTIME)
7 @Documented
8 public @interface ParamModel {
9 String value() default "";
10 }
复制代码

2.2 ModelExpander.java

复制代码
1 package com.moonciki.strongfeign.model.expander;
2
3 import com.alibaba.fastjson.JSON;
4 import feign.Param;
5 import lombok.extern.slf4j.Slf4j;
6
7 import java.util.Map;
8
9 @Slf4j
10 public class ModelExpander implements Param.Expander {
11
12 public String expand(Object value) {
13 String objectJson = JSON.toJSONString(value);
14 return objectJson;
15 }
16
17 @Override
18 public String expandWithName(Object value, String name) {
19 String valueExpand = null;
20
21 if(value != null){
22 if(name != null) {
23 try {
24 Map jsonMap = (Map)JSON.toJSON(value);
25
26 Object getValue = jsonMap.get(name);
27 if(getValue != null){
28 valueExpand = getValue.toString();
29 }
30 } catch (Exception e) {
31 log.error("GET VALUE ERROR:", e);
32 }
33 }else {
34 valueExpand = value.toString();
35 }
36 }
37
38 return valueExpand;
39 }
40 }
复制代码
注:该类需依赖 fastjson,也可根据个人需要修改该方法。

2.3 ParamModelParameterProcessor.java

复制代码
1 package com.moonciki.strongfeign.model.processor;
2
3 import com.moonciki.strongfeign.model.annotation.ParamModel;
4 import com.moonciki.strongfeign.model.expander.ModelExpander;
5 import feign.MethodMetadata;
6 import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;
7
8 import java.lang.annotation.Annotation;
9 import java.lang.reflect.Field;
10 import java.lang.reflect.Method;
11 import java.util.Collection;
12
13
14 public class ParamModelParameterProcessor implements AnnotatedParameterProcessor {
15
16 private static final Class ANNOTATION = ParamModel.class;
17
18 public Class<? extends Annotation> getAnnotationType() {
19 return ANNOTATION;
20 }
21
22 @Override
23 public boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method) {
24
25 int parameterIndex = context.getParameterIndex();
26 Class parameterType = method.getParameterTypes()[parameterIndex];
27 MethodMetadata data = context.getMethodMetadata();
28
29 Field[] fields = parameterType.getDeclaredFields();
30
31 for(Field field: fields) {
32 String name = field.getName();
33 context.setParameterName(name);
34
35 Collection query = context.setTemplateParameter(name, (Collection)data.template().queries().get(name));
36 data.template().query(name, query);
37 }
38 data.indexToExpander().put(context.getParameterIndex(), new ModelExpander());
39
40 return true;
41 }
42 }
复制代码

  1. 使用注解配置 feign Contract 对象

复制代码
1 @Bean
2 public Contract feignContract(){
3 List processors = new ArrayList<>();
4 processors.add(new ParamModelParameterProcessor());
5 processors.add(new PathVariableParameterProcessor());
6 processors.add(new RequestHeaderParameterProcessor());
7 processors.add(new RequestParamParameterProcessor());
8 return new SpringMvcContract(processors);
9 }
复制代码

  1. 使用方法示例

复制代码
1 @Primary
2 @FeignClient(value = "/user", fallback = UserClientFallback.class)
3 public interface UserClient {
4
5 /**
6 * demo post
7 * @return
8 */
9 @PostMapping("/demoPost")
10 Result demoPost(@ParamModel UserAccount userAccount);
11
12 /**
13 * demo get
14 * @return
15 */
16 @GetMapping("/demoGet")
17 Result demoPost(@ParamModel UserAccount userAccount);
18
19
20 }
复制代码
使用时,只需要在对象前加 @ParamModel 注解即可

需要同时传递对象及基本类型参数时, @ParamModel 可以与 @RequestParam("jobName") 同时使用在不同参数上。
原文地址https://www.cnblogs.com/moonciki/p/11320548.html

相关文章
|
11天前
|
JavaScript Android开发
Spring-boot-devTools无效解决办法,idea中devtools不起作用
Spring-boot-devTools无效解决办法,idea中devtools不起作用
|
30天前
|
负载均衡 Java API
Spring Cloud 面试题及答案整理,最新面试题
Spring Cloud 面试题及答案整理,最新面试题
132 1
|
30天前
|
Java Nacos Sentinel
Spring Cloud Alibaba 面试题及答案整理,最新面试题
Spring Cloud Alibaba 面试题及答案整理,最新面试题
138 0
|
1月前
|
SpringCloudAlibaba Java 持续交付
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
【构建一套Spring Cloud项目的大概步骤】&【Springcloud Alibaba微服务分布式架构学习资料】
131 0
|
2天前
|
负载均衡 Java 开发者
细解微服务架构实践:如何使用Spring Cloud进行Java微服务治理
【4月更文挑战第17天】Spring Cloud是Java微服务治理的首选框架,整合了Eureka(服务发现)、Ribbon(客户端负载均衡)、Hystrix(熔断器)、Zuul(API网关)和Config Server(配置中心)。通过Eureka实现服务注册与发现,Ribbon提供负载均衡,Hystrix实现熔断保护,Zuul作为API网关,Config Server集中管理配置。理解并运用Spring Cloud进行微服务治理是现代Java开发者的关键技能。
|
3天前
|
Java API 对象存储
对象存储OSS产品常见问题之使用Spring Cloud Alibaba情况下文档添加水印如何解决
对象存储OSS是基于互联网的数据存储服务模式,让用户可以安全、可靠地存储大量非结构化数据,如图片、音频、视频、文档等任意类型文件,并通过简单的基于HTTP/HTTPS协议的RESTful API接口进行访问和管理。本帖梳理了用户在实际使用中可能遇到的各种常见问题,涵盖了基础操作、性能优化、安全设置、费用管理、数据备份与恢复、跨区域同步、API接口调用等多个方面。
22 2
|
7天前
|
Java Spring
玩转对象掌控权:深入Spring,精准控制对象创建次数
玩转对象掌控权:深入Spring,精准控制对象创建次数
12 0
|
7天前
|
Java 关系型数据库 MySQL
高级对象装配:解析Spring创建复杂对象的秘诀
高级对象装配:解析Spring创建复杂对象的秘诀
21 0
高级对象装配:解析Spring创建复杂对象的秘诀
|
11天前
|
Nacos
SpringCloud Feign使用
SpringCloud Feign使用
21 1
|
17天前
|
负载均衡 网络协议 Java
构建高效可扩展的微服务架构:利用Spring Cloud实现服务发现与负载均衡
本文将探讨如何利用Spring Cloud技术实现微服务架构中的服务发现与负载均衡,通过注册中心来管理服务的注册与发现,并通过负载均衡策略实现请求的分发,从而构建高效可扩展的微服务系统。