当前位置:网站首页>Feign implements path escape through custom annotations
Feign implements path escape through custom annotations
2022-06-28 04:57:00 【qq_ forty-three million four hundred and seventy-nine thousand 】
High quality resource sharing
| Learning route guidance ( Click unlock ) | Knowledge orientation | Crowd positioning |
|---|---|---|
| 🧡 Python Actual wechat ordering applet 🧡 | Progressive class | This course is python flask+ Perfect combination of wechat applet , From the deployment of Tencent to the launch of the project , Create a full stack ordering system . |
| Python Quantitative trading practice | beginner | Take you hand in hand to create an easy to expand 、 More secure 、 More efficient quantitative trading system |

This article mainly explains how to implement user-defined coding for the path in the route through annotation
background
Recently, due to the need of , So you have to go through Feign Encapsulate a pair of Harbor Operation of the sdk Information .
During the call, it is found that , When the request parameter contains "/“ when ,Feign The default will be ”/" Resolve as a path , Instead of parsing as a complete parameter , Examples are as follows
The request path is :api/v2.0/projects/{projectName}/repositories
The annotation parameter is :@PathVariable(“projectName”)
The normal request is :api/v2.0/projects/test/repositories
Exception path is :api/v2.0/projects/test/pro/repositories
I believe careful students have found the above differences , natural {projectName} The corresponding value in is test, But the abnormal one is test/pro, So when an abnormal request hits harbor The machine of , Is interpreted as api/v2.0/projects/test/pro/repositories, So it's going to go straight back to 404
The above is the background , So let's talk about the solution
Solution
First we know that springboot The default is the processor with several annotation parameters
@MatrixVariableParameterProcessor
@PathVariableParameterProcessor
@QueryMapParameterProcessor
@RequestHeaderParameterProcessor
@RequestParamParameterProcessor
@RequestPartParameterProcessor
Because our request parameters are in the path , So by default we will use @PathVariableParameterProcessor To identify path parameters , The parameters we need to escape are also in the path , So let's take a look first @PathVariableParameterProcessor How is it realized
public boolean processArgument(AnnotatedParameterProcessor.AnnotatedParameterContext context, Annotation annotation, Method method) {
String name = ((PathVariable)ANNOTATION.cast(annotation)).value();
Util.checkState(Util.emptyToNull(name) != null, "PathVariable annotation was empty on param %s.", new Object[]{context.getParameterIndex()});
context.setParameterName(name);
MethodMetadata data = context.getMethodMetadata();
String varName = '{' + name + '}';
if (!data.template().url().contains(varName) && !this.searchMapValues(data.template().queries(), varName) && !this.searchMapValues(data.template().headers(), varName)) {
data.formParams().add(name);
}
return true;
}
In fact, in the source code ,springboot I didn't do anything magical , Is to get and use PathVariable Annotated parameters , Then add it to fromParams You can do that. .
Seeing here, can we think of , Now that we can get the corresponding parameters here , It is not up to us to decide what we want to do , Next, just do it ,
First, we declare an annotation of our own ,
import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.*;
/**
* @CreateAt: 2022/6/11 0:46
* @ModifyAt: 2022/6/11 0:46
* @Version 1.0
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface 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;
}
After the annotation is declared , We need to customize our own parameter parser , Inherit first 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;
}
}
You can see the code above , After we get the parameters of the custom annotation , Add the current parameter to the punch Param after , And specify a custom encoding format for the current parameter .
Last , We'll pass it again Bean Add the corresponding annotation to the container in the form of
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
*/
@Component
public class SlashBean {
@Bean
public Contract feignContract(){
List<AnnotatedParameterProcessor> processors=new ArrayList<>();
processors.add(new SlashPathVariableParameterProcessor());
return new SpringMvcContract(processors);
}
}
Finally, we annotate the above parameters PathVariable Replace it with our custom @SlashPathVariable, And it's done
Last
If you inject in the above form , It will pour into Spring overall situation , Therefore, it is necessary to consider whether it conforms to the scenario
If there is something not very clear or wrong , Welcome to correct
If you like, you may as well like it
边栏推荐
- [noip2002 popularization group] cross the river pawn
- 公司为什么选择云数据库?它的魅力到底是什么!
- [matlab traffic light identification] traffic light identification [including GUI source code 1908]
- Learning Tai Chi Maker - mqtt Chapter 2 (V) heartbeat mechanism
- 判断对象中是否存在某一个属性
- Multi thread implementation rewrites run (), how to inject and use mapper file to operate database
- 灵活的IP网络测试工具——— X-Launch
- Role of native keyword
- Distributed transaction - Final consistency scheme based on message compensation (local message table, message queue)
- 高通平台 Camera 之 MCLK 配置
猜你喜欢

UI automation test framework construction - write an app automation

恭喜我自己,公众号粉丝破万

2022高处安装、维护、拆除考试题及答案

并发之wait/notify说明

MySQL gets the current date of the year

Audio and video technology development weekly
![[applet] solution document using font awesome Font Icon (picture and text)](/img/1b/d1b738e6e35e59cc4a417df4ea0e8d.png)
[applet] solution document using font awesome Font Icon (picture and text)
![[NOIP2002 普及组] 过河卒](/img/6c/31fa210e08c7fd07691a1c5320154e.png)
[NOIP2002 普及组] 过河卒

The second round of free public classes of the red team is coming ~ 8:00 tomorrow night!

Sword finger offer 53 - I. find the number I in the sorted array (improved bisection)
随机推荐
华为9年经验的软件测试总监工作感悟—写给还在迷茫的朋友
Meta universe standard forum established
100+数据科学面试问题和答案总结 - 机器学习和深度学习
JS reverse massive star map sign signature
Multi thread implementation rewrites run (), how to inject and use mapper file to operate database
C语言中函数是什么?编程中的函数与数学中的函数区别?理解编程语言中的函数
Audio and video technology development weekly
CUPTI error: CUPTI could not be loaded or symbol could not be found.
几百行代码实现一个脚本解释器
UI automation test framework construction - write an app automation
109. 简易聊天室12:实现客户端一对一聊天
A bit of knowledge - online resources on Chinese Learning
2022烟花爆竹经营单位安全管理人员特种作业证考试题库及模拟考试
quartus 复制IP核
wordpress zibll子比主题6.4.1开心版 免授权
Severe tire damage: the first rock band in the world to broadcast live on the Internet
Notepad++ -- column editing mode -- Usage / instance
Simulation questions and answers of the latest national fire-fighting facility operators (primary fire-fighting facility operators) in 2022
短视频本地生活版块成为热门,如何把握新的风口机遇?
PHP code wechat, official account and enterprise wechat send emoticons [u+1f449]