Spring cloud Feign不支持对象传参解决办法[完美解决]
Spring cloud Feign不支持对象传参解决办法[完美解决]
spring cloud 使用 Feign 进行服务调用时,不支持对象参数。 通常解决方法是,要么把对象每一个参数平行展开,并使用 @RequestParam 标识出每一个参数,要么用 @RequestBody 将请求改为 body 传参,虽然这样解决了问题,但是这样限制了传参方式,并且使代码变得很繁重。 以下为完美解决 Feign 对象传参问题的办法。
- 引入如下依赖(可以在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 中央仓库。
-
创建如下三个类
开始时,打算把以下三个类加进仓库中,但由于如下三个类内容不多,并且有很多定制化的可能,因此单独实现。 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 }
复制代码
- 使用注解配置 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 @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
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
自己动手写Spring框架--IOC、MVC
自己动手写Spring框架--IOC、MVC对于一名Java开发人员,我相信没有人不知道 Spring 框架,而且也能够轻松就说出 Spring 的特性-- IOC、MVC、AOP、ORM(batis)。 看那么多 Spring 源码分析,不如自己动手写 个轻量的 Spring 框架。 下面我想简单介绍一下我写的轻量级的 Spring 框架(swift-framework),并且进行核心逻辑的分析,和使用说明。 提示:以下有大量图片,可以在新页面查看图片。 目录: 自己动手写Spring框架--IOC、MVC -- 怎么使用 swift-framework 框架 -- 跟着 debug 走流程 自己动手写Spring框架--AOP、ORM -- 敬请期待 怎么使用 swift-framework 框架 下载jar包,引入到自己的新项目中。再要做的就是很简单了。 示例: @Controller 注解:标注controller类。@Inject 注解:依赖注入类,自动注入依赖的实现类。@Action(value = "get:/hello") 注解:标注访问行为,‘get’是请求类型,‘...
- 下一篇
Java模拟并解决缓存穿透
Java模拟并解决缓存穿透什么叫做缓存穿透缓存穿透只会发生在高并发的时候,就是当有10000个并发进行查询数据的时候,我们一般都会先去redis里面查询进行数据,但是如果redis里面没有这个数据的时候,那么这10000个并发里面就会有很大一部分并发会一下子都去mysql数据库里面进行查询了 解决缓存穿透首先我模拟一下缓存穿透比如下面的代码在这里插入图片描述Pom.xml代码 <?xml version="1.0" encoding="UTF-8"?> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>springboot</artifactId> <version>0.0.1-SNA...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8安装Docker,最新的服务器搭配容器使用
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS8编译安装MySQL8.0.19
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Hadoop3单机部署,实现最简伪集群
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS6,7,8上安装Nginx,支持https2.0的开启