当前位置:网站首页>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
边栏推荐
猜你喜欢
OracleData安装问题
开关电源电压型与电流型控制
Light collector, Yunnan Baiyao!
学习太极创客 — MQTT 第二章(五)心跳机制
Distributed transaction - Final consistency scheme based on message compensation (local message table, message queue)
LeetCode 88:合并两个有序数组
测试开发必备技能:安全测试漏洞靶场实战
[noip2002 popularization group] cross the river pawn
[early knowledge of activities] list of recent activities of livevideostack
电源插座是如何传输电的?困扰小伙伴这么多年的简单问题
随机推荐
学习太极创客 — MQTT 第二章(六)MQTT 遗嘱
深度强化学习笔记
Is it better for a novice to open a securities account? Is it safe to open a stock account
并发之wait/notify说明
[early knowledge of activities] list of recent activities of livevideostack
代码理解:IMPROVING CONVOLUTIONAL MODELS FOR HANDWRITTEN TEXT RECOGNITION
A doctor's 22 years in Huawei (full of dry goods)
100+ data science interview questions and answers Summary - machine learning and deep learning
2022年安全员-A证考试题库及模拟考试
学习太极创客 — MQTT 第二章(五)心跳机制
乔布斯在斯坦福大学的演讲稿——Follow your heart
穿越封锁的最新利器,速度最快梯没有之一。
[Matlab bp regression prediction] GA Optimized BP regression prediction (including comparison before optimization) [including source code 1901]
Why is the frame rate calculated by opencv wrong?
Learning Tai Chi Maker - mqtt Chapter 2 (V) heartbeat mechanism
109. 简易聊天室12:实现客户端一对一聊天
QCOM LCD调试
别卷!如何高质量地复现一篇论文?
Multi thread implementation rewrites run (), how to inject and use mapper file to operate database
?位置怎么写才能输出true