feignclient注解作用,feign支持哪些注解

  feignclient注解作用,feign支持哪些注解

  

目录

背景解决方案最后

 

  

背景

近期由于项目中需要,所以需要通过假装封装一个对海港操作的软件开发工具包信息。

 

  在调用的过程中发现,当请求参数中带有/时,假装默认会将/当成路径去解析,而不是当成完整的一个参数解析,实例如下

  请求路径为:API/v 2.0/projects/{项目名称}/储存库

  注解参数为:@PathVariable(projectName )

  正常请求为:API/v 2.0/项目/测试/存储库

  异常路径为:API/2.0/project/test/pro/repositories

  相信细心的同学已经发现上面的差异了,正常的{项目名称}中对应的值为测试,而异常的却对应为测试/专业版,所以当异常的请求打到海港的机器时,被解析为API/v 2.0/projects/test/pro/repositories,所以会直接返回404

  以上就是背景了,所以接下来我们讨论一下解决方案

  

解决方案

首先我们知道跳羚中默认是带有几种注释参数处理器的

 

  @ MatrixVariableParameterProcessor @ pathfvariableparameterprocessor @ QueryMapParameterProcessor @ RequestPartParameterProcessor因为我们的请求参数是在路径中的,所以默认我们会使用@路径可变参数处理器来标识路径参数,而我们需要转义的参数其实也是在路径中,所以我们先来看一下@路径可变参数处理器是如何实现的

  公共布尔进程参数(AnnotatedParameterProcessor .AnnotatedParameterContext上下文,注释批注,方法方法){ String name=((路径变量)批注。cast(注释)).value();util。checkstate(util。emptytonull(名字)!=null,"参数%s上的路径变量批注为空",新对象[]{上下文。getparameter index()});语境。设置parametername(名称);方法元数据数据=上下文。getmethod元数据();String varName= { name }如果(!data.template().url().包含(varName)!这个。searchmapvalues(数据。模板().queries()、varName)!这个。searchmapvalues(数据。模板().headers()、varName)) { data.formParams().添加(姓名);}返回真实}其实在源码中,跳靴并没有做什么神器的事情,就是获取使用了路径变量注解的参数,然后再将其添加到fromParams中就可以。

  看到这里我们是不是可以想到,既然在这里我们可以拿到对应的参数了,那想做什么事情不都是由我们自己来决定了,接下来说干就干,

  首先我们声明一个属于自己的注解,

  导入org。spring框架。核心。注释。的别名;导入Java。郎。注释。*;/* * * * @创建于: 2022/6/11 0:46 * @修改于: 2022/6/11 0:46 * @版本1.0 */@Target(ElementType .参数)@Retention(RetentionPolicy .运行时)@Documentedpublic @interf

  ace SlashPathVariable { /** * Alias for {@link #name}. */ @AliasFor("name") String value() default ""; /** * The name of the path variable to bind to. * @since 4.3.3 */ @AliasFor("value") String name() default ""; /** * Whether the path variable is required. * <p>Defaults to {@code true}, leading to an exception being thrown if the path * variable is missing in the incoming request. Switch this to {@code false} if * you prefer a {@code null} or Java 8 {@code java.util.Optional} in this case. * e.g. on a {@code ModelAttribute} method which serves for different requests. * @since 4.3.3 */ boolean required() default true;}声明完注解后,我们就需要来自定义自己的参数解析器了,首先继承AnnotatedParameterProcessor

  

import feign.MethodMetadata;import feign.Util;import lombok.Data;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;import org.springframework.web.bind.annotation.PathVariable;import java.lang.annotation.Annotation;import java.lang.reflect.AnnotatedType;import java.lang.reflect.Method;import java.net.URLEncoder;import java.nio.charset.Charset;import java.util.Collection;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.stream.Collectors;/** * @CreateAt: 2022/6/11 0:36 * @ModifyAt: 2022/6/11 0:36 * @Version 1.0 */public class SlashPathVariableParameterProcessor implements AnnotatedParameterProcessor { private static final Class<SlashPathVariable> ANNOTATION=SlashPathVariable.class; @Override public Class<? extends Annotation> getAnnotationType() { return (Class<? extends Annotation>) ANNOTATION; } @Override public boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method) { MethodMetadata data = context.getMethodMetadata(); String name = ANNOTATION.cast(annotation).value(); Util.checkState(Util.emptyToNull(name) != null, "SlashPathVariable annotation was empty on param %s.", new Object[]{context.getParameterIndex()}); context.setParameterName(name); data.indexToExpander().put(context.getParameterIndex(),this::expandMap); return true; } private String expandMap(Object object) { String encode = URLEncoder.encode(URLEncoder.encode(object.toString(), Charset.defaultCharset()), Charset.defaultCharset()); return encode; }}

可以看到上面的代码,我们获取到自定义注解的参数后,将当前参数添加打Param后,并且为当前参数指定自定义的编码格式。

 

  最后,我们再通过Bean的形式将对应的注解添加到容器中

  

import feign.Contract;import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;import org.springframework.cloud.openfeign.support.SpringMvcContract;import org.springframework.context.annotation.Bean;import org.springframework.stereotype.Component;import java.util.ArrayList;import java.util.List;/** * @CreateAt: 2022/6/11 0:48 * @ModifyAt: 2022/6/11 0:48 * @Version 1.0 */@Componentpublic class SlashBean { @Bean public Contract feignContract(){ List<AnnotatedParameterProcessor> processors=new ArrayList<>(); processors.add(new SlashPathVariableParameterProcessor()); return new SpringMvcContract(processors); }}

最后我们将上面的参数注解PathVariable换成我们自定义的@SlashPathVariable,就大功告成了

 

  

 

  

最后

通过以上的形式进行注入的话,会注入到Spring全局,所以在使用的过程中需要考虑是否符合场景

 

  以上就是Feign利用自定义注解实现路径的转义详解的详细内容,更多关于Feign路径的转义的资料请关注盛行IT其它相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: