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

相关文章
|
18天前
|
JSON Java 数据格式
【微服务】SpringCloud之Feign远程调用
本文介绍了使用Feign作为HTTP客户端替代RestTemplate进行远程调用的优势及具体使用方法。Feign通过声明式接口简化了HTTP请求的发送,提高了代码的可读性和维护性。文章详细描述了Feign的搭建步骤,包括引入依赖、添加注解、编写FeignClient接口和调用代码,并提供了自定义配置的示例,如修改日志级别等。
40 1
|
1月前
|
前端开发 Java Spring
【Spring】“请求“ 之后端传参重命名,传递数组、集合,@PathVariable,@RequestPart
【Spring】“请求“ 之后端传参重命名,传递数组、集合,@PathVariable,@RequestPart
24 2
|
2月前
|
负载均衡 Java Nacos
SpringCloud基础2——Nacos配置、Feign、Gateway
nacos配置管理、Feign远程调用、Gateway服务网关
SpringCloud基础2——Nacos配置、Feign、Gateway
|
2月前
|
前端开发 API 微服务
SpringCloud微服务之间使用Feign调用不通情况举例
SpringCloud微服务之间使用Feign调用不通情况举例
407 2
|
2月前
|
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的问题
298 0
|
4月前
|
资源调度 Java 调度
Spring Cloud Alibaba 集成分布式定时任务调度功能
Spring Cloud Alibaba 发布了 Scheduling 任务调度模块 [#3732]提供了一套开源、轻量级、高可用的定时任务解决方案,帮助您快速开发微服务体系下的分布式定时任务。
14886 28
|
4月前
|
负载均衡 Java Spring
Spring cloud gateway 如何在路由时进行负载均衡
Spring cloud gateway 如何在路由时进行负载均衡
473 15
|
4月前
|
Java Spring
spring cloud gateway在使用 zookeeper 注册中心时,配置https 进行服务转发
spring cloud gateway在使用 zookeeper 注册中心时,配置https 进行服务转发
107 3
|
4月前
|
消息中间件 Java Nacos
通用快照方案问题之通过Spring Cloud实现配置的自动更新如何解决
通用快照方案问题之通过Spring Cloud实现配置的自动更新如何解决
75 0