Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to solve the problem that asynchronous threads can not get Session

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces how to solve the problem that asynchronous threads can not get Session, which can be used for reference by interested friends. I hope you can learn a lot after reading this article.

It is not easy for us to switch the login authorization function of the original project from Shiro to access SSO single sign-on service, because there are many systems, there are always some coquettish operations that we did not expect.

For example, start a thread on the thread that processes the request, get the Session in the new thread, and get the login user from the Session.

This is really a coquettish operation!

Due to not taking this situation into account, Bug came out online, but fortunately it is not a very serious problem.

We don't discuss what's wrong with such a coquettish operation and how to solve the problem. Find all kinds of such coquettish operations and modify them? It's hard! There is not so much time to change slowly, and you need to go through the testing process after the change.

I argued with my colleagues about this matter, after all, this problem did not arise before, but there was a problem when I switched to SSO (SDK encapsulated for easy access to SSO services). It is not my problem but whose problem is it.

There is no problem with the code in the above figure after testing, and the test results are shown in the following figure.

First of all, we need to know that the Session ID is created by the server and responds to the browser through the response header cookie. The browser stores the Session ID locally, automatically carries the Session ID on the next request, and sends the cookie request hair to the server.

When the server receives a client request, if the client has Session ID with it, then the Session is obtained according to Session ID. By default, it is fetched from memory. If you use the Shiro framework and use Redis to store Session, it is obtained from Redis.

If the Session expires or the client does not pass the Session ID, a new Session is created and the Session ID is reassigned to the new Session.

When the Shrio framework receives the request, it gets the Session ID through the filter and stores it in the ThreadLocal, so there is no need to get the Session through HttpServletRequest.

The reason why Shrio supports the ability to get Session in asynchronous threads is that Shrio uses InheritableThreadLocal instead of ThreadLocal, and implements passing Session ID to child threads, thus implementing "asynchronous context" passing Session.

But this is also limited, requiring that the asynchronous thread must be created by the thread currently processing the request before the Session ID can be passed to the child thread through InheritableThreadLocal, and if it is in the thread pool, it may not be available.

Here is a question for you: why can't you get it in the online pool, but it doesn't have to be out of reach? To understand this problem requires an understanding of the thread pool's working principle, source code, and InheritableThreadLocal source code, so I won't analyze it in this article.

So when we solve Bug, we replace ThreadLocal with InheritableThreadLocal, and implement set session and remove session operations through method interceptor (HandlerInterceptor) or filter (Filter), which is recommended.

In addition, as can be seen from the source code of the webmcv framework, RequestContextHolder#getRequestAttributes also supports InheritableThreadLocal, but it is not supported by default, and the configuration needs to be modified.

The getRequestAttributes method tries to get it from InheritableThreadLocal, with the following source code.

But whether you can get it or not depends on whether it is written or not:

The setRequestAttributes method is called by the RequestContextFilter filter, which is automatically configured by the webmvc framework as follows.

The default RequestContextFilter does not write ServletRequestAttributes to InheritableThreadLocal, as shown below.

So, whether we can replace the default registered RequestContextFilter and configure threadContextInheritable as true so that we can support passing Session ID to child threads, as shown in the following code.

However, this is not valid, because after RequestContextFilter, DispatcherServlet calls RequestContextHolder#setRequestAttributes again, and the incoming threadContextInheritable is false, clearing the previous writes, so you have to change the threadContextInheritable of DispatcherServlet to true to support it. However, this change is not recommended in the encapsulated SDK.

As to why threadContextInheritable defaults to false, the official API document in RequestContextFilter gives the following explanation.

Thank you for reading this article carefully. I hope the article "how to solve the problem that asynchronous threads can not get Session" shared by the editor will be helpful to you. At the same time, I also hope you can support us and pay attention to the industry information channel. More related knowledge is waiting for you to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report