目录
一,概述
在 Web 应用程序中,我们经常要跟踪用户身份。例如:当一个用户登录成功后,如 果他继续访问其他页面, Web 程序如何才能识别出该用户身份? 因为 HTTP 协议是一个无状态协议,即 Web 应用程序无法区分收到的两个 HTTP 请求是否是同一个浏览器发出的。为了跟踪用户状态,服务器可以向浏览器分配一个唯 一ID,并以 Cookie 的形式发送到浏览器,浏览器在后续访问时总是附带此 Cookie ,这样,服务器就可以识别用户身份。
二,Session会话追踪
我们把这种基于唯一ID识别用户身份的机制称为 Session 。每个用户第一次访问 服务器后,会自动获得一个 Session ID 。如果用户在一段时间内没有访问服务器,那 么 Session 会自动失效,下次即使带着上次分配的 Session ID 访问,服务器也认为 这是一个新用户,会分配新的 Session ID 。一次 Session 会话中往往包含着若干次 request 请求。 JavaEE 的 Servlet 机制内建了对 Session 的支持。当我们需要获取 Session 时,可以通过 request 请求对象的 getSession() 方法。
获取 HttpSession 后,常见的操作方法有:
void setAttribute(String name, Object value) :将指定 Key-Value 键值 对,存入当前 Session 会话中。
Object getAttribute(String name) :按照指定的 Key 从当前 Session 会话 中获取 Value ,返回值为 Object 类型的对象,如果不存在,则返回 null 。
void removeAttribute(String name) :按照指定的 Key 从当前 Session 会 话中删除 Key-Value 键值对。
long getCreationTime() :获取当前 Session 会话的创建时间。
long getLastAccessedTime() :获取当前 Session 会话最后一次请求的访问时间。
String getId() :获取当前 Session 会话的 SESSION ID 。 服务器识别 Session 的关键就是依靠一个名为 JSESSIONID 的 Cookie 。在 Servlet 中第一次调用 req.getSession() 时, Servlet 容器自动创建一个 Session I D ,然后通过一个名为 JSESSIONID 的 Cookie 发送给浏览器
使用 Session 时,由于服务器把所有用户的 Session 都存储在内存中,如果遇到内存不足的情况,就 需要把部分不活动的 Session 序列化到磁盘上,这会大大降低服务器的运行效率,因此,放入 Session 的数据不能太大,否则会影响服务器的运行。
代码实现一:
测试获取session_id,session的创建时间,和session的最后访问时间
package Test;
import java.io.IOException;
import java.util.Date;
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;
import javax.xml.crypto.Data;
@WebServlet("/demo.do")
public class SessionDemoServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest requst, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session=requst.getSession();
System.out.println("SESSION ID:"+session.getId());
System.out.println("SESSION创建时间:"+new Date(session.getCreationTime()));
System.out.println("SESSION最后访问:"+new Date(session.getLastAccessedTime()));
}
}
运行结果:
代码实现二:
测试session
生成幸运数字,并存入会话
package Test;
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("/three.do")
public class ThreeServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session=req.getSession();
System.out.println("本次会话:"+session.getId());
int LuckyNumber=(int)(Math.random()*100);
System.out.println("本次幸运数字:"+LuckyNumber);
session.setAttribute(session.getId(), LuckyNumber);
System.out.println();
}
}
获取会话中的幸运数字,并输出
package Test;
import java.io.IOException;
import java.io.PrintWriter;
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("/testSession.do")
public class TestSessionServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session=req.getSession();
System.out.println("本次会话:"+session.getId());
String result=String.valueOf(session.getAttribute(session.getId()));
PrintWriter out=resp.getWriter();
out.write(result);
out.flush();
}
}
可以观察到两次会话的session_id是一样的,是同一个会话。
三,Cookie
实际上, Servlet 提供的 HttpSession 本质上就是通过一个名为 JSESSIONID 的 Cookie 来跟踪用户会话的。除了这个名称外,其他名称的 Cookie 我们可以任意使 用。 创建一个新 Cookie 时,除了指定名称和值以外,通常需要设置 setPath("/") , 浏览器根据此前缀决定是否发送 Cookie 。
如果一个 Cookie 调用了 setPath("/use r/") ,那么浏览器只有在请求以 /user/ 开头的路径时才会附加此 Cookie 。通过 set MaxAge() 设置 Cookie 的有效期,单位为秒,最后通过 resp.addCookie() 把它添加到响应。 通过创建 Cookie ,我们可以实现在客户端浏览器中存储数据的目的,例如保存用 户名和密码。在 Chrome 浏览器中,单个 Cookie 的长度不能超过 4069 个字符(包 括 name,但不包括 = 号)。 我们可以在浏览器看到服务器发送的 Cookie ,以百度为例:
四,代码实现
测试cookie
package s7;
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 resp) throws ServletException, IOException {
System.out.println("cookie");
//创建Cookie对象
Cookie cookie1 =new Cookie("phone_number","13720721794");
//设置过期时间
cookie1.setMaxAge(60*60*24*7);
Cookie cookie2 =new Cookie("user_name","guby");
Cookie cookie3=new Cookie("user_pwd","123456");
//响应
resp.addCookie(cookie1);//将Cookie添加至响应头
resp.addCookie(cookie2);
resp.addCookie(cookie3);
}
}
获取cookie
package s7;
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("/get_cookie.do")
public class TestGetCookieServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("测试获取Cookie!");
//获取该客户端浏览器本次请求头(Request Header)中所有的Cookie
Cookie[] cookieArray=req.getCookies();
if(cookieArray!=null) {
for (Cookie cookie : cookieArray) {
System.out.println(cookie.getName());
System.out.println(cookie.getValue());
System.out.println();
}
}
}
}
运行结果:
小结:
Servlet 容器提供了 Session 机制以跟踪用户;
默认的 Session 机制是以 Cookie 形式实现的, Cookie 名称为 JSESSIONID ;
通过读写 Cookie 可以在客户端存储数据;