当前位置:网站首页>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
边栏推荐
- 2022年安全员-A证考试题库及模拟考试
- Understanding the source of innovation II
- [applet] solution document using font awesome Font Icon (picture and text)
- 2022年材料员-通用基础(材料员)操作证考试题库及答案
- CUPTI error: CUPTI could not be loaded or symbol could not be found.
- Is it better for a novice to open a securities account? Is it safe to open a stock account
- 公司为什么选择云数据库?它的魅力到底是什么!
- Feign remote call fallback callback failed, no effect
- Code understanding: implementing volume models for hangwriten text recognition
- CUPTI error: CUPTI could not be loaded or symbol could not be found.
猜你喜欢

Code understanding: implementing volume models for hangwriten text recognition
![[noip2002 popularization group] cross the river pawn](/img/6c/31fa210e08c7fd07691a1c5320154e.png)
[noip2002 popularization group] cross the river pawn

代码理解:IMPROVING CONVOLUTIONAL MODELS FOR HANDWRITTEN TEXT RECOGNITION

论文详读:IMPROVING CONVOLUTIONAL MODELS FOR HANDWRITTEN TEXT RECOGNITION

如何从零设计一款牛逼的高并发架构(建议收藏)

The number of small stores in Suning has dropped sharply by 428 in one year. Zhangkangyang, the son of Zhang Jindong, is the actual controller

Necessary skills for test and development: actual combat of security test vulnerability shooting range

2022新版nft源码中国元宇宙数字藏品艺术品交易平台源码

华为9年经验的软件测试总监工作感悟—写给还在迷茫的朋友

短视频本地生活版块成为热门,如何把握新的风口机遇?
随机推荐
MySQL gets the current date of the year
开关电源电压型与电流型控制
大促场景下,如何做好网关高可用防护
Learning Tai Chi Maker - mqtt Chapter II (VI) mqtt wills
Sword finger offer 47 Maximum gift value (DP)
The development of the Internet has promoted the emergence of a series of new models such as unbounded retail, digital retail and instant retail
[CSP-J2020] 优秀的拆分
UI automation test framework construction - write an app automation
控制器的功能和工作原理
The second round of free public classes of the red team is coming ~ 8:00 tomorrow night!
如何从零设计一款牛逼的高并发架构(建议收藏)
JS reverse massive star map sign signature
摄像头基础知识
Distributed transaction - Final consistency scheme based on message compensation (local message table, message queue)
Where does the storm go? Whose pot is the weather forecast wrong?
【牛客网刷题系列 之 Verilog快速入门】~ 四选一多路器
CI & CD must be known!
Cgo+gsoap+onvif learning summary: 8. Summary of arm platform cross compilation operation and common problems
学习太极创客 — MQTT 第二章(六)MQTT 遗嘱
知识点滴 - 关于汉语学习的网络资源