简体   繁体   English

Java中会话管理的最佳选择

[英]Best option for Session management in Java

Best way managing session in Java. 在Java中管理会话的最佳方式。 I heard that cookies are not reliable option for this as they gets stored into browser and can be accessed later on? 我听说cookie不是可靠的选项,因为它们存储在浏览器中,以后可以访问? Is this correct? 它是否正确? If possible please come up with the answers with the coding example. 如果可能的话,请用编码示例提出答案。

Which is the best among: 哪个是最好的:

  • URL Rewriting : Server will add an additional parameter at the end of URL link URL重写 :服务器将在URL链接的末尾添加一个附加参数
  • Hidden parameter in Form : server will add an additional parameter at every form in HTML Form :server中的隐藏参数将在HTML中的每个表单中添加一个附加参数
  • cookie : Server will ask browser to maintain a cookie. cookie :服务器会要求浏览器维护cookie。

The session management (client identification, cookie handling, saving session scoped data and so on) is basically already done by the appserver itself. 会话管理(客户端标识,cookie处理,保存会话范围数据等)基本上已由appserver本身完成。 You don't need to worry about it at all. 您根本不需要担心它。 You can just set/get Java objects in the session by HttpSession#setAttribute() and #getAttribute() . 您可以通过HttpSession#setAttribute()#getAttribute()在会话中设置/获取Java对象。 Only thing what you really need to take care of is the URL rewriting for the case that the client doesn't support cookies. 您真正需要处理的唯一事情是客户端不支持cookie的情况下的URL重写 It will then append a jsessionid identifier to the URL. 然后它会将一个jsessionid标识符附加到URL。 In the JSP you can use the JSTL's c:url for this. 在JSP中,您可以使用JSTL的c:url In the Servlet you can use HttpServletResponse#encodeURL() for this. 在Servlet中,您可以使用HttpServletResponse#encodeURL() This way the server can identify the client by reading the new request URL. 这样,服务器可以通过读取新请求URL来识别客户端。

Your new question shall probably be "But how are cookies related to this? How does the server do it all?". 您的新问题可能是“但是,如何与此相关?服务器如何做到这一切?”。 Well, the answer is this: if the server receives a request from a client and the server side code (your code) is trying to get the HttpSession by HttpServletRequest#getSession() while there's no one created yet (first request in a fresh session), the server will create a new one itself. 嗯,答案是这样的:如果服务器收到来自客户端的请求,并且服务器端代码(您的代码)正在尝试通过HttpServletRequest#getSession()获取HttpSession ,而尚未创建任何人(在新会话中的第一个请求) ),服务器将自己创建一个新的。 The server will generate a long, unique and hard-to-guess ID (the one which you can get by HttpSession#getId() ) and set this ID as a value of the cookie with the name jsessionid . 服务器将生成一个冗长,唯一且难以猜测的ID(您可以通过HttpSession#getId()获取该ID)并将此ID设置为名为jsessionid的cookie的值。 Under the hood the server uses HttpServletResponse#addCookie() for this. 在引擎盖下,服务器使用HttpServletResponse#addCookie() Finally the server will store all sessions in some kind of Map with the session ID as key and the HttpSession as value. 最后,服务器将所有会话存储在某种Map ,其中会话ID为密钥, HttpSession为值。

According to the HTTP cookie spec the client is required to send the same cookies back in the headers of the subsequent request. 根据HTTP cookie规范 ,客户端需要在后续请求的标头中发回相同的cookie。 Under the hood the server will search for the jsessionid cookie by HttpServletRequest#getCookies() and determine its value. 在引擎盖下,服务器将通过HttpServletRequest#getCookies()搜索jsessionid cookie并确定其值。 This way the server is able to obtain the associated HttpSession and give it back by every call on HttpServletRequest#getSession() . 这样,服务器就能够获得相关的HttpSession并通过HttpServletRequest#getSession()上的每次调用将其返回。

To the point: the only thing which is stored in the client side is the session ID (in flavor of a cookie) and the HttpSession object (including all of its attributes) is stored in the server side (in Java's memory). 至关重要:存储在客户端的唯一内容是会话ID(在cookie的风格中), HttpSession对象(包括其所有属性)存储在服务器端(在Java的内存中)。 You don't need to worry about session management youself and you also don't need to worry about the security. 您无需担心自己的会话管理,也无需担心安全问题。

See also: 也可以看看:

All Java web frameworks support cookies or URL-encoded session IDs. 所有Java Web框架都支持cookie或URL编码的会话ID。 They will chose the correct approach automatically, so there is nothing you need to do. 他们会自动选择正确的方法,因此您无需做任何事情。 Just request the session object from your container and it will handle the details. 只需从容器中请求会话对象,它就会处理细节。

[EDIT] There are two options: Cookies and a special URL. [编辑]有两种选择:Cookie和特殊网址。 There are problems with both approaches. 两种方法都存在问题。 For example, if you encode the session in an URL, people can try to pass the session on (by putting the URL into a mail, for example). 例如,如果您在URL中对会话进行编码,则人们可以尝试传递会话(例如,通过将URL放入邮件中)。 If you want to understand this, read a couple of articles about security and build app servers. 如果您想了解这一点,请阅读一些有关安全性和构建应用服务器的文章。 Otherwise: Your Java app server will do the right thing for you. 否则:您的Java应用服务器将为您做正确的事情。 Don't think about it. 不要考虑它。

cookie只存储会话ID,一旦会话过期,该ID就无用了。

Servlet specification defines the API for accessing/setting session data in standard J2EE application. Servlet规范定义了用于在标准J2EE应用程序中访问/设置会话数据的API。 Also it defines that session data is stored on the server-side and nothing is transferred to the client except the session identifier. 此外,它还定义会话数据存储在服务器端,除会话标识符外没有任何内容传输到客户端。 There are 2 mechanisms how session id is transferred: 会话ID的转换方式有两种:

1) request URL eg jessionid=.... 1)请求URL,例如jessionid = ....
2) cookie 2)cookie

Mechanism is determined automatically based on client capabilities. 机制是根据客户端功能自动确定的。

EDIT . 编辑 There is no best option, there is servlet specification that defines the way. 没有最好的选择,有servlet规范定义方式。

Http is a stateless, client-side pull only protocol. Http是一种无状态的,客户端的仅拉式协议。

To implement a stateful conversation over it, Java EE Web Server need to hide some information (which is sessionid) in client-side and the mechanism it can use should follow HTTP and HTML spec. 要在其上实现有状态会话,Java EE Web Server需要在客户端隐藏一些信息(即sessionid),并且它可以使用的机制应该遵循HTTP和HTML规范。

There are three ways to accomplish this goal: 有三种方法可以实现这一目标:

  1. URL Rewriting : Server will add an additional parameter at the end of URL link. URL重写 :服务器将在URL链接的末尾添加一个附加参数。
  2. Hidden parameter in Form : server will add an additional parameter at every form in HTML. Form :server中的隐藏参数将在HTML中的每个表单中添加一个附加参数。
  3. cookie : Server will ask browser to maintain a cookie. cookie :服务器会要求浏览器维护cookie。

Basically, modern web server will have a "filter" to choose which way to use automatically. 基本上,现代Web服务器将有一个“过滤器”来选择自动使用的方式。
So if Server detected that browser already turn off cookie support, it will switch to other ways. 因此,如果服务器检测到浏览器已经关闭cookie支持,它将切换到其他方式。

2 important questions: 2个重要问题:

  1. Which web technology are you using? 您使用的是哪种网络技术? JSF, Struts, SpringMVC or just plain servlets/JSPs. JSF,Struts,SpringMVC或只是简单的servlet / JSP。

    • Servlets/JSPs already give you the session support you need. Servlets / JSP已经为您提供了所需的会话支持。
      JSP Example: Hello, <%= session.getAttribute( "theName" ) %> JSP示例: Hello, <%= session.getAttribute( "theName" ) %>

    • I really don't think you have something to worry about cookies, since the data is stored safely in the server and handeling the cookie is done automaticlly. 我真的不认为你有什么担心cookie,因为数据安全地存储在服务器中,并且自动完成cookie的操作。

  2. Is your application installed on a single server? 您的应用程序是否安装在单个服务器上?

    • If YES than you have no problem, use the servlet session option. 如果是,则没有问题,请使用servlet会话选项。

    • if NO than you gotta find another way to do this. 如果不是你要找到另一种方法来做到这一点。 Like using a sticky session, or maybe parse the entire session object in the requests/responses as a field. 就像使用粘性会话一样,或者可以将请求/响应中的整个会话对象解析为字段。 This option indeed requires you to take security measures. 此选项确实要求您采取安全措施。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM