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

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

以下为完美解决 Feign 对象传参问题的办法。

1. 引入如下依赖(可以在maven仓库中搜索 strongfeign)

 <dependency>
<groupId>com.moonciki.strongfeign</groupId>
<artifactId>feign-httpclient</artifactId>
<version>10.2.3</version>
</dependency>

该源码修改自 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 中央仓库。

2. 创建如下三个类

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

2.1 ParamModel.java

 package com.moonciki.strongfeign.model.annotation;

 import java.lang.annotation.*;

 @Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ParamModel {
String value() default "";
}

2.2 ModelExpander.java

 package com.moonciki.strongfeign.model.expander;

 import com.alibaba.fastjson.JSON;
import feign.Param;
import lombok.extern.slf4j.Slf4j; import java.util.Map; @Slf4j
public class ModelExpander implements Param.Expander { public String expand(Object value) {
String objectJson = JSON.toJSONString(value);
return objectJson;
} @Override
public String expandWithName(Object value, String name) {
String valueExpand = null; if(value != null){
if(name != null) {
try {
Map<String, Object> jsonMap = (Map<String, Object>)JSON.toJSON(value); Object getValue = jsonMap.get(name);
if(getValue != null){
valueExpand = getValue.toString();
}
} catch (Exception e) {
log.error("GET VALUE ERROR:", e);
}
}else {
valueExpand = value.toString();
}
} return valueExpand;
}
}

注:该类需依赖 fastjson,也可根据个人需要修改该方法。

2.3 ParamModelParameterProcessor.java

 package com.moonciki.strongfeign.model.processor;

 import com.moonciki.strongfeign.model.annotation.ParamModel;
import com.moonciki.strongfeign.model.expander.ModelExpander;
import feign.MethodMetadata;
import org.springframework.cloud.openfeign.AnnotatedParameterProcessor; import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection; public class ParamModelParameterProcessor implements AnnotatedParameterProcessor { private static final Class<ParamModel> ANNOTATION = ParamModel.class; public Class<? extends Annotation> getAnnotationType() {
return ANNOTATION;
} @Override
public boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method) { int parameterIndex = context.getParameterIndex();
Class parameterType = method.getParameterTypes()[parameterIndex];
MethodMetadata data = context.getMethodMetadata(); Field[] fields = parameterType.getDeclaredFields(); for(Field field: fields) {
String name = field.getName();
context.setParameterName(name); Collection query = context.setTemplateParameter(name, (Collection)data.template().queries().get(name));
data.template().query(name, query);
}
data.indexToExpander().put(context.getParameterIndex(), new ModelExpander()); return true;
}
}

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

     @Bean
public Contract feignContract(){
List<AnnotatedParameterProcessor> processors = new ArrayList<>();
processors.add(new ParamModelParameterProcessor());
processors.add(new PathVariableParameterProcessor());
processors.add(new RequestHeaderParameterProcessor());
processors.add(new RequestParamParameterProcessor());
return new SpringMvcContract(processors);
}

4. 使用方法示例

 @Primary
@FeignClient(value = "/user", fallback = UserClientFallback.class)
public interface UserClient { /**
* demo post
* @return
*/
@PostMapping("/demoPost")
Result demoPost(@ParamModel UserAccount userAccount); /**
* demo get
* @return
*/
@GetMapping("/demoGet")
Result demoPost(@ParamModel UserAccount userAccount); }

使用时,只需要在对象前加 @ParamModel  注解即可

需要同时传递对象及基本类型参数时, @ParamModel 可以与 @RequestParam("jobName")  同时使用在不同参数上。

Spring cloud Feign不支持对象传参解决办法[完美解决]的更多相关文章

  1. Spring Cloud Feign的文件上传实现

    在Spring Cloud封装的Feign中并不直接支持传文件,但可以通过引入Feign的扩展包来实现,本来就来具体说说如何实现. 原文:http://blog.didispace.com/sprin ...

  2. spring cloud feign不支持@RequestBody+ RequestMethod.GET,报错

    1.问题梳理: 异常:org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not ...

  3. 第六章:声明式服务调用:Spring Cloud Feign

    Spring Cloud Feign 是基于 Netflix Feign 实现的,整合了 Spring Cloud Ribbon 和 Spring Cloud Hystrix,除了提供这两者的强大功能 ...

  4. SpringCloud---声明式服务调用---Spring Cloud Feign

    1.概述 1.1 Spring Cloud Ribbon.Spring Cloud Hystrix的使用几乎是同时出现的,Spring Cloud提供了一个更高层次的封装这2个工具类框架:Spring ...

  5. RestTemplate OR Spring Cloud Feign 上传文件

    SpringBoot,通过RestTemplate 或者 Spring Cloud Feign,上传文件(支持多文件上传),服务端接口是MultipartFile接收. 将文件的字节流,放入ByteA ...

  6. datasnap远程方法支持自定义对象传参

    有同仁需要远程方法传输自定义的数据类型,他以为要自己写代码会很复杂,其实DATASNAP早就为我们想到了. datasnap的数据序列和还原真是无与伦比的强大,其远程方法支持自定义对象传参,DATAS ...

  7. SpringCloud:feign对象传参和普通传参及遇到的坑

    对象传参: #使用@RequestBody来指定传参对象 @RequestMapping(value = "/v2/matterCode/genCode", method = Re ...

  8. Spring Cloud Feign 如何使用对象参数

    概述 Spring Cloud Feign 用于微服务的封装,通过接口代理的实现方式让微服务调用变得简单,让微服务的使用上如同本地服务.但是它在传参方面不是很完美.在使用 Feign 代理 GET 请 ...

  9. 微服务实战SpringCloud之Spring Cloud Feign替代HTTP Client

    简介 在项目中我们有时候需要调用第三方的API,微服务架构中这种情况则更是无法避免--各个微服务之间通信.比如一般的项目中,有时候我们会使用 HTTP Client 发送 HTTP 请求来进行调用,而 ...

随机推荐

  1. InstallShield 2018 打包安装

    关于InstallShield 2018打包安装程序的使用 1. 下载InstallShield2018 建议使用新的版本,毕竟新的版本功能功能全.问题少.用户体验佳. 下载地址:http://www ...

  2. 爬虫之抓js教程

    在初学的爬虫过程中,很多人还不知道有些字段是如何生成的,怎样模拟生成这些字段来拼接头部.为了再次纪念[宏彦获水]成语初次面世,特地用[百度登陆]写下一篇登陆百度的教程,以供大家参考. 前面学习了如何在 ...

  3. asp.net core 系列之Configuration

    在ASP.NET Core中的App configuration 是通过configuration providers基于key-value对建立的.Configuration providers读取 ...

  4. 手动启动log4j|nginx实现http https共存

    手动加载log4j.xml文件 DOMConfigurator.configure("src/main/resources/log4j.xml"); log4j.propertie ...

  5. 论文阅读 <Relocalization, Global Optimization and Map Merging for Monocular Visual-Inertial SLAM>

    看了一下港科的基于vins拓展的论文<relocalization, global optimization and merging for vins>,在回环的实现部分总体没有什么变化, ...

  6. Java - 格式化输出JSON字符串的两种方式

    目录 1 使用阿里的fastjson 1.1 项目的pom.xml依赖 1.2 Java示例代码 2 使用谷歌的gson 2.1 项目的pom.xml依赖 2.2 Java示例代码 1 使用阿里的fa ...

  7. 整型,布尔值,字符串详解,for语句 练习

    2019 年 7 月 8 日 1.将今天的课上的代码敲一遍,然后整理笔记 已完成 2.有变量name = "aleX leNb" 完成如下操作: 移除 name 变量对应的值两边的 ...

  8. 【带着canvas去流浪(12)】用Three.js制作简易的MARVEL片头动画(上)

    目录 一. 大作业说明 二.基本思路 三.视频纹理表面修复--UV映射 3.1 问题描述 3.2 纹理贴图的基本原理-UV映射 3.3 关键示例代码 四.小结 示例代码托管在:http://www.g ...

  9. LiteIDE TARGETARGS -conf_path=E:/PokerServer/src/GameServer/conf/texas.xml -log_dir=E:/PokerServer/src/GameServer/main/log

    LiteIDE TARGETARGS -conf_path=E:/PokerServer/src/GameServer/conf/texas.xml -log_dir=E:/PokerServer/s ...

  10. 个人永久性免费-Excel催化剂功能第39波-DotNet版的正则处理函数

    在很久之前已经开发过的一些自定义函数,未能有详细的讲解,接下来几波中着重对之前开发过的自定义函数进行详细讲解及示例说明,希望能够帮助到普通用户们能顺利使用,此篇介绍为正则表达式函数. 文章出处说明 原 ...