当前位置:网站首页>Solution and principle analysis of feign call missing request header
Solution and principle analysis of feign call missing request header
2022-07-27 05:08:00 【wen-pan】
think feign Add cookie For example !!!! The process of adding other request header data is the same !!!
One 、 Ask questions
- We have two services A、B, Now users access through the browser A An interface to a service
- In this interface, you can use openFeign Called B service
- B There is an interceptor in the service , Intercept all requests , Check whether the request header contains cookie, If there is cookie This release , without cookie Then intercept
problem : We know openFeign When making remote calls, he will build a new RequestTemplate For the request , Because it is a newly initiated request , So of course, there is no browser in the request header cookie Data. , How to make this openFeign When requesting to bring the browser cookie Well ?
Two 、 Problem analysis
Through the introduction above , We know openFeign When making a remote call , Because it is a new request call , So he lost his original request ( Browser initiated ) Inside cookie Information and request header information .
Then can we put the original request cookie Take out the data , Then it's going on openFeign When calling, it is put into the new request ? Certainly. , This is what we will introduce below feign Principle of interceptor .
3、 ... and 、 Problem solving
①、 Create a feign Call the interceptor and inject into the container
@Configuration
public class FeignConfig {
@Bean("requestInterceptor")
public static RequestInterceptor requestInterceptor() {
// Create interceptor
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate template) {
// 1、 Use RequestContextHolder Get the request header information of the native request ( Environment retainer below )
// from ThreadLocal Get the request header ( Make sure that feign Invocation and controller The request is in the same thread environment )
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (requestAttributes != null) {
// obtain controller Request object
HttpServletRequest request = requestAttributes.getRequest();
// If you use a thread pool for remote calls , be request It's empty. ( because RequestContextHolder.getRequestAttributes() It's from threadlocal Li Na's value )
if (Objects.nonNull(request)) {
//2、 Get the old request cookie Information
String cookie = request.getHeader("Cookie");
// Sync Cookie ( Send the old request cookie Put the information into the new request (RequestTemplate))
template.header("Cookie", cookie);
}
}
}
};
}
}
②、 test
Start the remote call again , At this point, you will find that feign The request header of the call has cookie data
Four 、 Source code analysis
Add a
RequestInterceptorThe interceptor is solved feign Call the data problem in the lost request header , What did he do ? What's the mechanism ? Actually, take a look feign The source code of the call is known , It's simpleThe first thing to know is feign The underlying principle of invocation is based on dynamic proxy !!!
1、FeignInvocationHandler.invoke()
adopt debug We can see ,feign The call will eventually execute FeignInvocationHandler.invoke() Method
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("equals".equals(method.getName())) {
try {
Object otherHandler =
args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
return equals(otherHandler);
} catch (IllegalArgumentException e) {
return false;
}
} else if ("hashCode".equals(method.getName())) {
return hashCode();
} else if ("toString".equals(method.getName())) {
return toString();
}
// Here is the specific execution logic , Click in invoke
return dispatch.get(method).invoke(args);
}
2、SynchronousMethodHandler.invoke()
public Object invoke(Object[] argv) throws Throwable {
RequestTemplate template = buildTemplateFromArgs.create(argv);
Options options = findOptions(argv);
Retryer retryer = this.retryer.clone();
while (true) {
try {
// Specific implementation entry , Click in
return executeAndDecode(template, options);
} catch (RetryableException e) {
try {
retryer.continueOrPropagate(e);
} catch (RetryableException th) {
// Omit part of the code .... This is actually a failure retry , It has nothing to do with our theme
continue;
}
}
}
3、SynchronousMethodHandler.executeAndDecode()
- It can be seen that he built the request first Request
- And then through
client.execute(request, options);The real call initiated
Object executeAndDecode(RequestTemplate template, Options options) throws Throwable {
// 1、 structure request, The core is here , Click in
Request request = targetRequest(template);
Response response;
long start = System.nanoTime();
try {
// 2、 Where the call is actually initiated
response = client.execute(request, options);
response = response.toBuilder()
.request(request)
.requestTemplate(template)
.build();
} catch (IOException e) {
throw errorExecuting(request, e);
}
// Omit some irrelevant codes
}
4、SynchronousMethodHandler.targetRequest()
Request targetRequest(RequestTemplate template) {
// Here is our custom RequestInterceptor Where called
// You can see , He got all the implementations in the container RequestInterceptor Interface bean, Then execute their apply Method
for (RequestInterceptor interceptor : requestInterceptors) {
interceptor.apply(template);
}
return target.apply(template);
}
5、 summary
Through the above followed by a wave of source code , We know why openFeign How to add request header data , as follows :
- Inject a custom
RequestInterceptorInterface implementation classes into containers - openFeign The request will be built before calling Request, In the build request You will get our customized
RequestInterceptorAnd implement , In the custom RequestInterceptor The implementation class will get the request header information from the original request , And then put in feign Called request in
Note that if it is initiated through thread pool or multithreading feign call , Then through the above addition RequestInterceptor The implementation class passes RequestContextHolder.getRequestAttributes() It is impossible to obtain the request header data in the original request , How to solve this situation ? Actually, it's simple , The simplest way is to pass in the request header information when submitting the task to the thread pool . You can also use Ali's TransmittableThreadLocal.
边栏推荐
- 安装Pygame
- 自定义视口高度,多余的部分使用滚动
- Solution: read the files with different names in the two folders and deal with the files with different mappings
- Photoshop裁剪工具隐藏技巧
- STM32 Hal serial port (uart/usart) debugging experience (I) -- basic knowledge of serial port communication +hal library code understanding
- Advantages of smart exhibition hall design and applicable industry analysis
- 使用mq消息队列来进行下单流程的高并发设计,消息挤压,消息丢失,消息重复的产生场景和解决方案
- feign调用丢失请求头问题解决及原理分析
- Be diligent in talking about what sidelines you can do now
- The project connects with Alipay payment, and the intranet penetration realizes the monitoring of asynchronous callback notification of successful payment of Alipay
猜你喜欢

Web框架介绍

多态的详讲

Hiding skills of Photoshop clipping tool

Dialog introduction

OFDM 16 lecture 2-ofdm and the DFT

Plato farm is expected to further expand its ecosystem through elephant swap

How does PS import LUT presets? Photoshop import LUT color preset tutorial

Knapsack problem DP

使用ngrok做内网穿透

"Photoshop2021 introductory tutorial" flatten "perspective images
随机推荐
2019 top tennis cup upload
自定义视口高度,多余的部分使用滚动
vim的基本操作
Three paradigms, constraints, some keyword differences,
"Photoshop2021 introductory tutorial" flatten "perspective images
Event
TypeScript 详解
Reproduce ssa-gan using the nine day deep learning platform
How does PS import LUT presets? Photoshop import LUT color preset tutorial
QT 菜单栏、工具栏和状态栏
Plato farm is expected to further expand its ecosystem through elephant swap
On the problem that Gorm's beforedelete hook method does not work
How does the TCP server handle multiple client connections on one port (one-to-one or one to many)
Introduction to Web Framework
对话框数据传递
写代码涉及到的斜杠/和反斜杠\
Advantages of smart exhibition hall design and applicable industry analysis
传智教育|软件测试工程师未来的发展方向有哪些?
Another skill is to earn 30000 yuan a month+
Event Summary - common summary