在Web应用程序中,我们经常要跟踪用户身份。例如:当一个用户登录成功后,如果他继续访问其他页面,Web程序如何才能识别出该用户身份?当一个用户在操作自己的购物车时,Web程序如何才能识别出该用户身份?
因为HTTP协议是一个无状态协议,即Web应用程序无法区分收到的两个HTTP请求是否是同一个浏览器发出的。为了跟踪用户状态,服务器可以向浏览器分配一个唯一ID,并以Cookie的形式发送到浏览器,浏览器在后续访问时总是附带此Cookie,这样,服务器就可以识别用户身份。
Session。每个用户第一次访问服务器后,会自动获得一个Session ID。要想追踪session会话,我们必须首先获取到session。JavaEE的servlet机制内建了对session的支持,当我们需要获取Session时,可以通过request请求对象的getRequestedSessionId()方法。
- @WebServlet
- public class GetSession extends HttpServlet{
- @Override
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
- //获取到的sessionID为String的字符串类型
- String session = request.getRequestedSessionId();
- System.out.println("获取本次sessionID" + session);
-
- }
Session机制是以Cookie形式实现的 实际上,Servlet提供的HttpSession本质上就是通过一个名为JESSIONID的cookie来跟踪用户会话的。除了这个名称外,其他名称的Cookie我们可以任意使用。
创建一个新Cookie时,除了指定名称和值以外,通常需要设置setPath("/"),浏览器根据此前缀决定是否发送Cookie。如果一个Cookie调用了setPath("/user/"),那么浏览器只有在请求以/user/开头的路径时才会附加此Cookie。通过setMaxAge()设置Cookie的有效期,单位为秒,最后通过resp.addCookie()把它添加到响应。
通过创建Cookie,我们可以实现在客户端浏览器中存储数据的目的,例如保存用户名和密码。在Chrome浏览器中,单个 Cookie的长度不能超过 4069 个字符(包括 name,但不包括 = 号)。
如果我们想要读取一个Cookie,例如,在IndexServlet中,读取名为lang的Cookie以获取用户设置的语言,可以写一个方法如下:
- private String parseLanguageFromCookie(HttpServletRequest req) {
- // 获取请求附带的所有Cookie:
- Cookie[] cookies = req.getCookies();
- // 如果获取到Cookie:
- if (cookies != null) {
- // 循环每个Cookie:
- for (Cookie cookie : cookies) {
- // 如果Cookie名称为lang:
- if (cookie.getName().equals("lang")) {
- // 返回Cookie的值:
- return cookie.getValue();
- }
- }
- }
- // 返回默认值:
- return "en";
- }
当我们产生一个Session会话时,使用HTTPSessionListener监听器,就可以监听会话的开始与销毁,同样也可以获取该会话的JESSIONID。只需要调用该会话的getID()方法,具体的代码示例如下:
@WebListener
public class SessionListener implements HttpSessionListener, HttpSessionAttributeListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
HttpSession currentSession = se.getSession();
System.out.println("新的会话:"+currentSession.getId());}
}