带有 2 个不同请求的 HttpSession 问题 [英] troubles with HttpSession with 2 different requests
问题描述
我正在开发基于 Java 的后端,但在管理用户会话时遇到了问题.
I'm developing a Java based backend and I'm having troubles while managing my user sessions.
我想在会话中为每个用户存储一些个人信息,因此我实现了一个用于登录目的的 Servlet,如果登录成功,它会创建一个会话:
I would like to store some personal information for each user in the session, hence I implemented a Servlet for login purpose which creates a session if the login is successful:
@WebServlet("/LoginUserWithPassword")
@MultipartConfig(fileSizeThreshold = 1024 * 1024 * 2, // 2MB
maxFileSize = 1024 * 1024 * 10, // 10MB
maxRequestSize = 1024 * 1024 * 50) // 50MB
public class LoginUserWithPassword extends HttpServlet {
private static final long serialVersionUID = 1L;
static Logger log = Logger.getLogger(LoginUserWithPassword.class);
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
....
HttpSession session = request.getSession();
session.getServletContext().getContext("/{applicationContextRoot}").setAttribute("nom",usr.nom);
session.getServletContext().getContext("/{applicationContextRoot}").setAttribute("prenom", usr.prenom);
session.getServletContext().getContext("/{applicationContextRoot}").setAttribute("login", usr.email);
session.getServletContext().getContext("/{applicationContextRoot}").setAttribute("id", String.valueOf(usr.id_user));
session.getServletContext().getContext("/{applicationContextRoot}").setAttribute("id_right",String.valueOf(ur.id_right));
session.getServletContext().getContext("/{applicationContextRoot}").setAttribute("right",url.right);
session.getServletContext().getContext("/{applicationContextRoot}").setAttribute("session",session.getId());
然后,在客户端(JSP/Javascript),我正在检索会话信息.
then, on the client side (JSP/Javascript), I'm retrieving the session information.
考虑一个 user1,他使用以下 Javascript 代码在浏览器 (Chrome) 上成功登录:
Considering a user1, who is logging successfully on a browser (Chrome) with the following Javascript code:
Glogin = '<%= (String) (request.getSession().getServletContext().getContext("/{applicationContextRoot}").getAttribute("login")) %>';
Gsession = '<%= (String) (request.getSession().getServletContext().getContext("/{applicationContextRoot}").getAttribute("session")) %>';
console.log("login from session: "+Glogin);
console.log("Session ID: "+Gsession);
我可以看到以下控制台日志:
I can see the following console logs:
login from session: admin3@toto.com
Session ID: 7D6638EA7167580F4C1BD4D51FAD3C9C
然后我使用另一个浏览器 (FF) 在同一台计算机上对 user2 进行第二次登录,控制台日志中有以下内容:
Then I'm performing a second login of user2 on the same computer with another browser (FF), I have the following in the console logs:
login from session: admin@toto.com
Session ID: 376C57F6ACB08CD3B66AB8406DB72984
在那个阶段一切都很完美,我可以在每个会话中检索我各自的属性,但是如果我刷新 user1 的浏览器,我会检索用户 2 的会话 ID....并丢失我的 user1 会话上下文.
at that stage everything is perfect, I can retrieve my respective attributes on each session,but If I refresh the browser of user1, I retrieve the session ID of user 2....and lose my user1 session context.
你知道我为什么会有这种行为吗?可能是我实现会话管理的方式不正确?
Do you have an idea why I'm getting such behavior ? may be my way of implementing session management is not correct ?
推荐答案
不要把它放在 ServletContext 中,它会覆盖之前的值.而是将它放在当前会话中,如下所示:
Dont put it in ServletContext, it will override the previous values. Instead put it in the current session like given below:
request.getSession().setAttribute("nom",usr.nom);
并从像这样的会话中检索 JSP 上的这些值
And retrieve these values on JSP from session like
(String)session.getAttribute("nom");
目前您正在遵循类似
Browser(CLient) ---> War 1 上调用 JSP -----> war 2 上调用 Servlet
Browser(CLient) ---> Calling JSP on War 1 -----> Calling Servlet on war 2
您可以在浏览器(客户端)之间保持会话 ----> 在 war 1 上调用 JSP
You can maintain session between Browser(Client) ----> Calling JSP on war 1
当你验证你的用户时,用户的详细信息来自war 2,用户的详细信息可以被捕获为管道符号分隔在一个字符串中,字符串可以保存在ServletContext中(注意仅在war 2中执行此代码)
When you authenticate your user the details of Users from war 2, the details of users can be captured in as pipe symbol separated in a string that String can be saved in ServletContext (Note perform this code in war 2 only)
Map<String. String> allUsers = new HashMap<>();
// add key as user id and value is comma separated in string
ServletContext servletContext =request.getSession().getServletContext().getContext("contextPath")
servletContext.setAttribute("users",allUsers );
您的 servlet 应该将用户 ID 返回给 JSP 以作为响应
Your servlet should return user id to JSP in response
war 2 ----> 将 user id 返回给 war 1 中的 JSP
war 2 ----> returning user id to JSP in war 1
现在您应该将此用户 ID 保存在您在浏览器(客户端)-----> 战争 1 上的 JSP 之间维护的会话中.
Now you should save this user id in the session that you are maintaining between Browser (CLient) -----> JSP on war 1.
每当您想在 servlet 上下文中使用存储在 war 2 中的值时,您可以在 war 1 中的 JSP 中使用以下代码
Whenever you want to use values that you had stored in war 2 in servlet context, you can use below code in JSP in war 1
ServletContext servletContext =request.getSession().getServletContext().getContext("contextPath")
servletContext.getAttribute("user");
注意:您不能在两个 war 文件之间共享会话,但可以在它们之间共享对象.
Note : You can not share session between two war files however you can share objects between them.
愿这对你有帮助.
这篇关于带有 2 个不同请求的 HttpSession 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!