1. Overview
1.概述
In this tutorial, we’ll cover the handling of cookies and sessions in Java, using Servlets.
在本教程中,我们将介绍在Java中使用Servlets处理cookies和session。
Additionally, we’ll shortly describe what a cookie is, and explore some sample use cases for it.
此外,我们将很快描述什么是cookie,并探讨它的一些使用案例的例子。
2. Cookie Basics
2.饼干基础知识
Simply put, a cookie is a small piece of data stored on the client-side which servers use when communicating with clients.
简单地说,cookie是存储在客户端的一小段数据,服务器在与客户进行通信时使用它。
They’re used to identify a client when sending a subsequent request. They can also be used for passing some data from one servlet to another.
在发送后续请求时,它们被用来识别一个客户。它们也可用于将一些数据从一个Servlet传递给另一个。
For more details, please refer to this article.
更多的细节,请参考到这篇文章。
2.1. Create a Cookie
2.1.创建一个Cookie
The Cookie class is defined in the javax.servlet.http package.
Cookie类被定义在 javax.servlet.http包中。
To send it to the client, we need to create one and add it to the response:
为了将其发送给客户端,我们需要创建一个并将其添加到响应中。
Cookie uiColorCookie = new Cookie("color", "red");
response.addCookie(uiColorCookie);
However, its API is a lot broader – let’s explore it.
然而,它的API要宽泛得多–让我们来探讨一下。
2.2. Set the Cookie Expiration Date
2.2.设置Cookie的到期日
We can set the max age (with a method maxAge(int)) which defines how many seconds a given cookie should be valid for:
我们可以设置最大年龄(用一个方法maxAge(int)),它定义了一个给定的cookie应该有多少秒的有效期。
uiColorCookie.setMaxAge(60*60);
We set a max age to one hour. After this time, the cookie cannot be used by a client (browser) when sending a request and it also should be removed from the browser cache.
我们将最大年龄设定为一小时。在这个时间之后,客户端(浏览器)在发送请求时不能使用该cookie,而且它也应该从浏览器的缓存中删除。
2.3. Set the Cookie Domain
2.3.设置Cookie域
Another useful method in the Cookie API is setDomain(String).
Cookie API中另一个有用的方法是setDomain(String)。
This allows us to specify domain names to which it should be delivered by the client. It also depends on if we specify domain name explicitly or not.
这使我们能够指定客户端应向其交付的域名。这也取决于我们是否明确指定域名。
Let’s set the domain for a cookie:
让我们为一个cookie设置域。
uiColorCookie.setDomain("example.com");
The cookie will be delivered to each request made by example.com and its subdomains.
该cookie将被传递给example.com及其子域的每个请求。
If we don’t specify a domain explicitly, it will be set to the domain name which created a cookie.
如果我们没有明确指定一个域名,它将被设置为域名 创建了一个cookie。
For example, if we create a cookie from example.com and leave domain name empty, then it’ll be delivered to the www.example.com (without subdomains).
例如,如果我们从example.com创建一个cookie并将域名留空,那么它将被送到www.example.com(没有子域)。
Along with a domain name, we can also specify a path. Let’s have a look at that next.
除了域名之外,我们还可以指定一个路径。让我们接下来看看这个。
2.4. Set the Cookie Path
2.4.设置Cookie路径
The path specifies where a cookie will be delivered.
路径指定了一个cookie将被送到哪里。
If we specify a path explicitly, then a Cookie will be delivered to the given URL and all its subdirectories:
如果我们明确指定一个路径,那么一个Cookie将被送到指定的URL及其所有子目录:。
uiColorCookie.setPath("/welcomeUser");
Implicitly, it’ll be set to the URL which created a cookie and all its subdirectories.
隐含地,它将被设置为创建cookie的URL及其所有子目录。
Now let’s focus on how we can retrieve their values inside a Servlet.
现在让我们关注一下我们如何在Servlet内检索它们的值。
2.5. Read Cookies in the Servlet
2.5.在Servlet中读取Cookies
Cookies are added to the request by the client. The client checks its parameters and decides if it can deliver it to the current URL.
Cookies是由客户端添加到请求中的。客户端检查其参数并决定是否能将其传递到当前的URL。
We can get all cookies by calling getCookies() on the request (HttpServletRequest) passed to the Servlet.
我们可以通过在传递给Servlet的请求(HttpServletRequest)上调用getCookies()来获得所有cookie。
We can iterate through this array and search for the one we need, e.g., by comparing their names:
我们可以遍历这个数组,搜索我们需要的那一个,例如,通过比较它们的名字。
public Optional<String> readCookie(String key) {
return Arrays.stream(request.getCookies())
.filter(c -> key.equals(c.getName()))
.map(Cookie::getValue)
.findAny();
}
2.6. Remove a Cookie
2.6.删除一个Cookie
To remove a cookie from a browser, we have to add a new one to the response with the same name, but with a maxAge value set to 0:
要从浏览器中删除一个cookie,我们必须在响应中添加一个新的cookie,其名称相同,但maxAge值设置为0。
Cookie userNameCookieRemove = new Cookie("userName", "");
userNameCookieRemove.setMaxAge(0);
response.addCookie(userNameCookieRemove);
A sample use case for removing cookies is a user logout action – we may need to remove some data which was stored for an active user session.
删除cookie的一个示例用例是用户注销操作–我们可能需要删除为活动用户会话存储的一些数据。
Now we know how we can handle cookies inside a Servlet.
现在我们知道如何在Servlet内处理cookie。
Next, we’ll cover another important object which we access very often from a Servlet – a Session object.
接下来,我们将介绍另一个我们经常从Servlet访问的重要对象 – Session对象。
3. HttpSession Object
3.HttpSession对象
The HttpSession is another option for storing user-related data across different requests. A session is a server-side storage holding contextual data.
HttpSession是另一个用于在不同请求中存储用户相关数据的选项。会话是一个保存上下文数据的服务器端存储。
Data isn’t shared between different session objects (client can access data from its session only). It also contains key-value pairs, but in comparison to a cookie, a session can contain object as a value. The storage implementation mechanism is server-dependent.
数据在不同的会话对象之间不共享(客户端只能访问其会话中的数据)。它也包含键值对,但与cookie相比,会话可以包含对象作为一个值。存储实现机制是依赖于服务器的。
A session is matched with a client by a cookie or request parameters. More info can be found here.
一个会话通过cookie或请求参数与客户端相匹配。更多信息可以在这里找到。
3.1. Getting a Session
3.1.获得一个会话
We can obtain an HttpSession straight from a request:
我们可以直接从一个请求中获得一个HttpSession。
HttpSession session = request.getSession();
The above code will create a new session in case it doesn’t exist. We can achieve the same by calling:
上面的代码将创建一个新的会话,以防它不存在。我们也可以通过调用:
request.getSession(true)
In case we just want to obtain existing session and not create a new one, we need to use:
如果我们只是想获得现有的会话而不是创建一个新的会话,我们需要使用。
request.getSession(false)
If we access the JSP page for the first time, then a new session gets created by default. We can disable this behavior by setting the session attribute to false:
如果我们第一次访问JSP页面,那么就会默认创建一个新的会话。我们可以通过将session属性设置为false:来禁用这种行为。
<%@ page contentType="text/html;charset=UTF-8" session="false" %>
In most cases, a web server uses cookies for session management. When a session object is created, then a server creates a cookie with JSESSIONID key and value which identifies a session.
在大多数情况下,网络服务器使用cookie进行会话管理。当一个会话对象被创建时,服务器会创建一个带有JSESSIONID键和值的cookie,以识别一个会话。
3.2. Session Attributes
3.2.Session属性
The session object provides a bunch of methods for accessing (create, read, modify, remove) attributes created for a given user session:
会话对象提供了一堆方法,用于访问(创建、读取、修改、删除)为特定用户会话创建的属性。
- setAttribute(String, Object) which creates or replaces a session attribute with a key and a new value
- getAttribute(String) which reads an attribute value with a given name (key)
- removeAttribute(String) which removes an attribute with a given name
We can also easily check already existing session attributes by calling getAttributeNames().
我们也可以通过调用getAttributeNames()轻松检查已经存在的会话属性。
As we already mentioned, we could retrieve a session object from a request. When we already have it, we can quickly perform methods mentioned above.
正如我们已经提到的,我们可以从一个请求中检索一个会话对象。当我们已经有了它,我们可以快速执行上面提到的方法。
We can create an attribute:
我们可以创建一个属性。
HttpSession session = request.getSession();
session.setAttribute("attributeKey", "Sample Value");
The attribute value can be obtained by its key (name):
属性值可以通过其键(名称)获得。
session.getAttribute("attributeKey");
We can remove an attribute when we don’t need it anymore:
当我们不再需要一个属性时,我们可以删除它。
session.removeAttribute("attributeKey");
A well-known use case for a user session is to invalidate whole data it stores when a user logs out from our website. The session object provides a solution for it:
用户会话的一个众所周知的用例是,当用户从我们的网站上注销时,它所存储的全部数据将失效。会话对象为其提供了一个解决方案。
session.invalidate();
This method removes the whole session from the web server so we cannot access attributes from it anymore.
这个方法将整个会话从Web服务器上删除,所以我们不能再从它那里访问属性。
HttpSession object has more methods, but the one we mentioned are the most common.
HttpSession对象有更多的方法,但我们提到的是最常见的。
4. Conclusion
4.结论
In this article, we covered two mechanism which allows us to store user data between subsequent requests to the server – the cookie and the session.
在这篇文章中,我们介绍了两种机制,它们允许我们在后续的服务器请求之间存储用户数据–cookie和session。
Keep in mind that the HTTP protocol is stateless, and so maintaining state across requests is a must.
请记住,HTTP协议是无状态的,因此保持跨请求的状态是必须的。
As always, code snippets are available over on Github.
像往常一样,代码片段可在Github上获得。