一. 概述
在Web应用程序中,我们经常需要跟踪用户的身份。当用户访问一个页面或者对自己的购物车进行操作时,Web程序是如何识别用户身份的?
HTTP协议是无状态协议,即Web应用程序无法区分收到的HTTP请求是否是同一个浏览器发出的。为了跟踪用户状态,服务器向浏览器分配了一个唯一ID,并以Cookie的形式发送到服务器,服务器在后续访问时总是附带此Cookie
- 用户第一次访问服务器后,会自动创建Session并获得一个Session ID
- 根据Session ID,创建一个名称为”JSESSIONID“的Cookie, 将Session_ID保存在Cookie
- 接下来的每次发起请求时,客户端浏览器都会在请求中,添加JESSIONID,用于服务器确认身份。
2.如何获取Session?
HttpSession session = request.getSession();
服务器识别Session的关键就是依靠一个名为JSESSIONID的Cookie。
- 在Servlet第一次调用request.getSession()时,Servlet容器会自动创建一个Session ID,然后通过名为JSESSIONID的Cookie发送给浏览器
- 放入Session 的数据不能太大,否则会影响服务器的运行效率:
使用Session时,由于服务器把所有用户的Session都存储在内存中,如果遇到内存不足的情况,就把部分不活动地Session序列化到磁盘,这样会大大降低
服务器的运行效率。
【发送请求】
package com.ape.web.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet("/test_session.do")
public class TestSessionServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("GET请求:TestSessionServlet被请求到了!");
HttpSession session = req.getSession();
System.out.println(session.getId());
}
}
【运行结果】

- 如果用户一段时间内没有访问服务器,那么Session会自动失效。
- 下次访问即使带着上次分配的Session ID访问,服务器也会认为这是一个新用户,会分配新的Session ID。
- 一次Session会话中往往包含着若干次request请求。

当我们对服务器发送3次请求时,其Session ID一致:

Servlet提供的HttpSession本质上就是一个通过名为JSESSIONID的Cookie来跟踪用户会话的,除了这个名称外,其他名称的Cookie可以任意使用。

如果一个Cookie调用了setPath(“/user/”),那么浏览器只有在请求以"/user/"开头的路径时才会附加此Cookie。
【添加Cookies并设置过期时间】package com.ape.web.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/test_cookie.do")
public class TestCookieServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {
System.out.println("测试添加cookie!");
// 创建Cookie对象
Cookie cookie1 = new Cookie("phone_number", "18710404709");
cookie1.setMaxAge(60*60*24);
Cookie cookie2 = new Cookie("user_name", "旺旺仙贝");
cookie2.setMaxAge(60*60*24);
Cookie cookie3 = new Cookie("user_email", "31391@126.com");
cookie3.setMaxAge(60*60*24); // 24h
// 响应
response.addCookie(cookie1); // 将Cookie添加至响应头
response.addCookie(cookie2);
response.addCookie(cookie3);
}
}
我们可以在服务器中F12看查Cookies是否添加成功

【测试获取Cookie】
package com.ape.web.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/test_get_cookie_value.do")
public class TestGetCookieValueServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("测试获取Cookie");
// 获取该客户端本次请求头(Request Header)中所有的Cookie
Cookie[] cookieArray = request.getCookies();
for(Cookie ck : cookieArray) {
System.out.println(ck.getName());
System.out.println(ck.getValue());
System.out.println();
}
}
}
【运行结果】

4. 既然我们可以追踪到用户身份,那我们如何查看此用户的访问量呢?
package com.ape.web.servlet;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet("/application.do")
public class TestApplicationServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException {
// 会话范围
HttpSession session = request.getSession();
if(session.getAttribute("session_counter") != null) {
}
// 应用范围:不区分用户,访问量++
ServletContext application = request.getServletContext();
System.out.println("Context Path:" + application.getContextPath());
System.out.println("Real Path:" + application.getRealPath("/"));
if(application.getAttribute("app_counter") == null) {
application.setAttribute("app_counter", 1);
System.out.println("总访问量:1" );
}else {
int counter = Integer.parseInt(application.getAttribute("app_counter").toString());
application.setAttribute("app_counter", counter+1);
System.out.printf("总访问量:%d\n" ,counter+1);
}
}
}
【运行结果】
