当前位置:网站首页>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
边栏推荐
- Performance optimization and implementation of video codec
- [Matlab bp regression prediction] GA Optimized BP regression prediction (including comparison before optimization) [including source code 1901]
- [CSP-J2020] 优秀的拆分
- mysql导入文本文件时的pager
- The latest examination questions and answers for the eight members (standard members) of Liaoning architecture in 2022
- 多线程实现 重写run(),怎么注入使用mapper文件操作数据库
- ?位置怎么写才能输出true
- How to clean the nozzle of Epson l3153 printer
- 测试开发必备技能:安全测试漏洞靶场实战
- 2022年安全员-A证考试题库及模拟考试
猜你喜欢

MySQL gets the current date of the year
![[NOIP2002 普及组] 过河卒](/img/6c/31fa210e08c7fd07691a1c5320154e.png)
[NOIP2002 普及组] 过河卒
![[csp-j2020] excellent splitting](/img/05/90f9cf71791b3cdc37073eaf5db989.png)
[csp-j2020] excellent splitting

短视频本地生活版块成为热门,如何把握新的风口机遇?

基于微信小程序的婚纱影楼门户小程序

Huawei's 9-year experience as a software testing director
![[noip2002 popularization group] cross the river pawn](/img/6c/31fa210e08c7fd07691a1c5320154e.png)
[noip2002 popularization group] cross the river pawn

【Matlab BP回归预测】GA优化BP回归预测(含优化前的对比)【含源码 1901期】

Feign通过自定义注解实现路径的转义

Function and working principle of controller
随机推荐
Learning Tai Chi Maker - mqtt Chapter 2 (V) heartbeat mechanism
?位置怎么写才能输出true
Light collector, Yunnan Baiyao!
Google Earth engine (GEE) - global flood database V1 (2000-2018)
C语言中函数是什么?编程中的函数与数学中的函数区别?理解编程语言中的函数
【Matlab BP回归预测】GA优化BP回归预测(含优化前的对比)【含源码 1901期】
Sword finger offer 53 - I. find the number I in the sorted array (improved bisection)
Notepad++ -- common plug-ins
高通平台 Camera 之 MCLK 配置
OracleData安装问题
Mise en place d'un cadre d'essai d'automatisation de l'interface utilisateur - - rédaction d'une application d'automatisation
The latest examination questions and answers for the eight members (standard members) of Liaoning architecture in 2022
Unity delegate
One article explains in detail | those things about growth
汇编常用指令
2022年G3锅炉水处理复训题库模拟考试平台操作
一文详解|增长那些事儿
JS逆向之巨量星图sign签名
通过例子学习Rust
[csp-j2020] excellent splitting