当前位置:网站首页>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
边栏推荐
- Meta universe standard forum established
- MySQL gets the current date of the year
- Matlab exercises -- exercises related to symbolic operation
- 100+数据科学面试问题和答案总结 - 机器学习和深度学习
- The latest examination questions and answers for the eight members (standard members) of Liaoning architecture in 2022
- 别卷!如何高质量地复现一篇论文?
- 如何从零设计一款牛逼的高并发架构(建议收藏)
- 代码理解:IMPROVING CONVOLUTIONAL MODELS FOR HANDWRITTEN TEXT RECOGNITION
- Sword finger offer 53 - I. find the number I in the sorted array (improved bisection)
- 【微服务|OpenFeign】OpenFeign快速入门|基于Feign的服务调用
猜你喜欢

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

On the necessity of building a video surveillance convergence platform and its scenario application

Feign remote call fallback callback failed, no effect

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

Code understanding: implementing volume models for hangwriten text recognition

openssl客户端编程:一个不起眼的函数导致的SSL会话失败问题

Where does the storm go? Whose pot is the weather forecast wrong?

2022年全国最新消防设施操作员(初级消防设施操作员)模拟题及答案

Cgo+gsoap+onvif learning summary: 8. Summary of arm platform cross compilation operation and common problems

Meta universe standard forum established
随机推荐
[CSP-J2020] 优秀的拆分
Analysis of distributed transaction solution Seata golang
Simulation questions and answers of the latest national fire-fighting facility operators (primary fire-fighting facility operators) in 2022
cgo+gSoap+onvif学习总结:8、arm平台交叉编译运行及常见问题总结
Sword finger offer 49 Ugly number (three finger needling technique)
快速下载JDK,除了官方Oracle下载,还有国内可以有最新版本的下载地址吗
How to clean the nozzle of Epson l3153 printer
Google Earth engine (GEE) - global flood database V1 (2000-2018)
lotus v1.16.0 calibnet
Interview: what are the similarities and differences between abstract classes and interfaces?
Differences between pragma and ifndef
mysql导入文本文件时的pager
多线程实现 重写run(),怎么注入使用mapper文件操作数据库
100+数据科学面试问题和答案总结 - 机器学习和深度学习
机器人学DH参数及利用matlab符号运算推导
Play with double pointer
UI自动化测试框架搭建 —— 编写一个APP自动化
Huawei's 9-year experience as a software testing director
[NOIP2002 普及组] 过河卒
Learning Tai Chi Maker - mqtt Chapter II (VI) mqtt wills