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

相关文章
|
4月前
|
XML Java 测试技术
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
这篇文章介绍了Spring5框架的三个新特性:支持@Nullable注解以明确方法返回、参数和属性值可以为空;引入函数式风格的GenericApplicationContext进行对象注册和管理;以及如何整合JUnit5进行单元测试,同时讨论了JUnit4与JUnit5的整合方法,并提出了关于配置文件加载的疑问。
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
|
2月前
|
JSON Java 数据格式
【微服务】SpringCloud之Feign远程调用
本文介绍了使用Feign作为HTTP客户端替代RestTemplate进行远程调用的优势及具体使用方法。Feign通过声明式接口简化了HTTP请求的发送,提高了代码的可读性和维护性。文章详细描述了Feign的搭建步骤,包括引入依赖、添加注解、编写FeignClient接口和调用代码,并提供了自定义配置的示例,如修改日志级别等。
95 1
|
2月前
|
Java Spring
获取spring工厂中bean对象的两种方式
获取spring工厂中bean对象的两种方式
45 1
|
2月前
|
前端开发 Java Spring
【Spring】“请求“ 之后端传参重命名,传递数组、集合,@PathVariable,@RequestPart
【Spring】“请求“ 之后端传参重命名,传递数组、集合,@PathVariable,@RequestPart
32 2
|
2月前
|
前端开发 Java Spring
【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象
【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象
117 2
|
2月前
|
存储 Java 程序员
SpringIOC和DI的代码实现,Spring如何存取对象?@Controller、@Service、@Repository、@Component、@Configuration、@Bean DI详解
本文详细讲解了Spring框架中IOC容器如何存储和取出Bean对象,包括五大类注解(@Controller、@Service、@Repository、@Component、@Configuration)和方法注解@Bean的用法,以及DI(依赖注入)的三种注入方式:属性注入、构造方法注入和Setter注入,并分析了它们的优缺点。
31 0
SpringIOC和DI的代码实现,Spring如何存取对象?@Controller、@Service、@Repository、@Component、@Configuration、@Bean DI详解
|
3月前
|
负载均衡 Java Nacos
SpringCloud基础2——Nacos配置、Feign、Gateway
nacos配置管理、Feign远程调用、Gateway服务网关
SpringCloud基础2——Nacos配置、Feign、Gateway
|
3月前
|
前端开发 API 微服务
SpringCloud微服务之间使用Feign调用不通情况举例
SpringCloud微服务之间使用Feign调用不通情况举例
579 2
|
3月前
|
Java API 开发者
【已解决】Spring Cloud Feign 上传文件,提示:the request was rejected because no multipart boundary was found的问题
【已解决】Spring Cloud Feign 上传文件,提示:the request was rejected because no multipart boundary was found的问题
505 0
|
5月前
|
负载均衡 Java Spring
Spring cloud gateway 如何在路由时进行负载均衡
Spring cloud gateway 如何在路由时进行负载均衡
514 15
下一篇
无影云桌面