Spring cloud Feign不支持对象传参解决办法[完美解决]
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不支持对象传参解决办法[完美解决]的更多相关文章
- Spring Cloud Feign的文件上传实现
在Spring Cloud封装的Feign中并不直接支持传文件,但可以通过引入Feign的扩展包来实现,本来就来具体说说如何实现. 原文:http://blog.didispace.com/sprin ...
- spring cloud feign不支持@RequestBody+ RequestMethod.GET,报错
1.问题梳理: 异常:org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'POST' not ...
- 第六章:声明式服务调用:Spring Cloud Feign
Spring Cloud Feign 是基于 Netflix Feign 实现的,整合了 Spring Cloud Ribbon 和 Spring Cloud Hystrix,除了提供这两者的强大功能 ...
- SpringCloud---声明式服务调用---Spring Cloud Feign
1.概述 1.1 Spring Cloud Ribbon.Spring Cloud Hystrix的使用几乎是同时出现的,Spring Cloud提供了一个更高层次的封装这2个工具类框架:Spring ...
- RestTemplate OR Spring Cloud Feign 上传文件
SpringBoot,通过RestTemplate 或者 Spring Cloud Feign,上传文件(支持多文件上传),服务端接口是MultipartFile接收. 将文件的字节流,放入ByteA ...
- datasnap远程方法支持自定义对象传参
有同仁需要远程方法传输自定义的数据类型,他以为要自己写代码会很复杂,其实DATASNAP早就为我们想到了. datasnap的数据序列和还原真是无与伦比的强大,其远程方法支持自定义对象传参,DATAS ...
- SpringCloud:feign对象传参和普通传参及遇到的坑
对象传参: #使用@RequestBody来指定传参对象 @RequestMapping(value = "/v2/matterCode/genCode", method = Re ...
- Spring Cloud Feign 如何使用对象参数
概述 Spring Cloud Feign 用于微服务的封装,通过接口代理的实现方式让微服务调用变得简单,让微服务的使用上如同本地服务.但是它在传参方面不是很完美.在使用 Feign 代理 GET 请 ...
- 微服务实战SpringCloud之Spring Cloud Feign替代HTTP Client
简介 在项目中我们有时候需要调用第三方的API,微服务架构中这种情况则更是无法避免--各个微服务之间通信.比如一般的项目中,有时候我们会使用 HTTP Client 发送 HTTP 请求来进行调用,而 ...
随机推荐
- RQNOJ193 造路行动
题目转移 详见最小生成树讲解 Kruskal #include<cstdio> #include<algorithm> using namespace std; ; int n ...
- Flink会话窗口测试
Flink会话窗口测试 一.测试结论: 1.会话窗口的间隔时间和水位线作用一样,表示输出现在时间 - 间隔时间之前所有未结算时间的数据,作用类似于水位线,但是和水位线开闭不一样. 2.会话窗口显示的数 ...
- linux学习书籍推荐《鸟哥的Linux私房菜》下载
下载地址:点我 <鸟哥的Linux私房菜:基础学习篇>是具有知名度的Linux入门书<鸟哥的Linux私房菜基础学习篇>的最新版,全面而详细地介绍了Linux操作系统.< ...
- extern和static区别
1. 声明和定义 当定义一个变量的时候,就包含了对该变量声明的过程,同时在内存张申请了一块内存空间.如果在多个文件中使用相同的变量,为了避免重复定义,就必须将声明和定义分离开来.定义是创建与名字关 ...
- ~~Python文件简单操作~~
进击のpython Python文件操作 在说Python的文件操作之前 我们可以先思考一个问题 平时我们是怎么对电脑中的文件进行操作的呢? 打开电脑⇨找到文件⇨打开文件⇨读文件⇨修改文件⇨保存文件⇨ ...
- shell的用处到底大不大
我曾在智联招聘等网站上搜寻有关shell脚本员的职位,与C++.JAVA等热门语言相比,冷清很多.看上去似乎招shell程序员的公司比较少.是不是公司不重视或者是很少用到shell这个东东呢? ...
- java高并发系列 - 第12天JUC:ReentrantLock重入锁
java高并发系列 - 第12天JUC:ReentrantLock重入锁 本篇文章开始将juc中常用的一些类,估计会有十来篇. synchronized的局限性 synchronized是java内置 ...
- 构建工具--glup如何压缩,丑化代码
目录 为什么使用 实现 为什么使用 最近在迭代公司的项目,发现项目有如下缺点: 代码没有压缩,js文件,内存大,放在服务器上占空间: 源代码没有混淆或者丑化处理,本公司的程序员写出来的代码和高质量逻辑 ...
- python 之 并发编程(守护进程、互斥锁、IPC通信机制)
9.5 守护进程 主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就立即终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic process ...
- React躬行记(9)——组件通信
根据组件之间的嵌套关系(即层级关系)可分为4种通信方式:父子.兄弟.跨级和无级. 一.父子通信 在React中,数据是自顶向下单向流动的,而父组件通过props向子组件传递需要的信息是组件之间最常见的 ...