会话:一次会话中包含多次请求和响应。
一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止。
概念:客户端会话技术,将数据保存到客户端
使用步骤:
new Cookie(String name,String value)response.addCookie(Cookie cookie)Cookie[] request.getCookies()为方便创建 Servlet 实现类,在 IDEA 中修改代码模板,按下图方式操作

@WebServlet("/cookieTest01")
public class CookieTest01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 创建 Cookie 对象
Cookie cookie = new Cookie("msg", "Hello");
// 2. 发送 Cookie 对象
response.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
@WebServlet( "/cookieTest02")
public class CookieTest02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 3. 获取 Cookie 对象
Cookie[] cookies = request.getCookies();
// 获取数据,遍历 Cookies
if (cookies!=null){
for (Cookie cookie : cookies) {
String name = cookie.getName();
String value = cookie.getValue();
System.out.println(name+":"+value);
}
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
过程解释(以上述代码为例):
msg:Hello);set-cookie:msg=Hello(键值对形式) ;msg=Hello)保存到客户端浏览器上,等到下一次发送请求时,客户端会将这个数据带到服务器;cookie:msg=Hello(键值对形式),在服务器中可以获取请求头中的数据,一般使用 JavaWeb 封装好的 API 进行操作可以创建多个 Cookie 对象,使用 Response 对象调用多次
addCookie()方法发送 Cookie 对象即可
@WebServlet( "/cookieTest03")
public class CookieTest03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie cookie01 = new Cookie("msg", "Hello");
Cookie cookie02 = new Cookie("name", "John");
response.addCookie(cookie01);
response.addCookie(cookie02);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
setMaxAgent(int seconds)
@WebServlet( "/cookieTest04")
public class CookieTest04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 创建 Cookie 对象
Cookie cookie = new Cookie("msg", "setMaxAge()");
// 设置 Cookie 的存活时间
cookie.setMaxAge(30); // 将 Cookie 持久化到硬盘,30秒后就会自动删除 Cookie 文件
// 发送 Cookie
response.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
setPath(String path):设置 Cookie 的获取范围,默认情况下为设置的当前的虚拟目录。如果要进行数据共享。则可以将 path 设置为 "/"@WebServlet("/cookieTest05")
public class CookieTest05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie cookie = new Cookie("msg", "你好!");
// 设置 path ,让当前的服务器下的部署的所有项目共享 Cookie 信息
cookie.setPath("/");
response.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
setDomain(String path) :如果设置一级域名相同,那么多个服务器之间的 Cookie 可以共享数据(例如:setDomain(".baidu.com") 那么 tieba.baidu.com 和 news.baidu.com 中的 Cookie 就可以共享)特点:
作用:
需求:
分析:
@WebServlet( "/cookieTest06")
public class CookieTest06 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置相应的消息体的数据格式以及编码
response.setContentType("text/html;charset=utf-8");
// 获取所有 Cookie
Cookie[] cookies = request.getCookies();
boolean flag=false; // 没有 Cookie 为 lastTime
// 遍历 Cookie 数组
if (cookies!=null&&cookies.length>0){
for (Cookie cookie : cookies) {
// 获取 Cookie 的名称
String name = cookie.getName();
// 判断名称是否是:lastTime
if ("lastTime".equals(name)){
// 有该 Cookie,不是第一次访问
flag=true; // 有 lastTime 的 Cookie
// 设置 Cookie 的 value
// 获取当前时间的字符串,重新设置 Cookie 的值,重新发送 Cookie
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_date = simpleDateFormat.format(date);
System.out.println("编码前:"+str_date);
// URL 编码
str_date = URLEncoder.encode(str_date, "utf-8");
System.out.println("编码后:"+str_date);
cookie.setValue(str_date);
// 设置 Cookie 的存活时间
cookie.setMaxAge(60*60*24); // 一天
response.addCookie(cookie);
// 响应数据
// 获取 Cookie 的 value、时间
String value = cookie.getValue();
System.out.println("解码前:"+value);
// URL 解码
value= URLDecoder.decode(value,"utf-8");
System.out.println("解码后:"+value);
response.getWriter().write("欢迎回来,您上次访问时间为:"
+value+"");
break;
}
}
}
if (cookies==null||cookies.length==0||flag==false){
// 没有,第一次访问
// 设置 Cookie 的 value
// 获取当前时间的字符串,重新设置 Cookie 的值,重新发送 Cookie
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_date = simpleDateFormat.format(date);
System.out.println("编码前:"+str_date);
// URL 编码
str_date = URLEncoder.encode(str_date, "utf-8");
System.out.println("编码后:"+str_date);
Cookie cookie = new Cookie("lastTime",str_date);
// 设置 Cookie 的存活时间
cookie.setMaxAge(60*60*24); // 一天
response.addCookie(cookie);
response.getWriter().write("您好,欢迎您首次访问!
");
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中,使用 HttpSession 对象。
HttpSession session = request.getSession();Object getAttribute(String name)void setAttribute(String name,Object value)void removeAttribute(String name)@WebServlet("/sessionTest01")
public class SessionTest01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 使用 Session 共享数据
// 获取 Session 对象
HttpSession session = request.getSession();
// 存储数据
session.setAttribute("msg","Hello,Session!");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
@WebServlet("/sessionTest02")
public class SessionTest02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取 Session 对象
HttpSession session = request.getSession();
// 获取数据
Object msg = session.getAttribute("msg");
System.out.println(msg);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
服务器是如何确保在一次会话范围内,多次获取的 Session 对象使用一个的?
Session 的实现是依赖于 Cookie 的!(Cookie 是依赖于请求头和响应头实现的)
set-cookie:JSESSIONID=ID 值 (set-cookie 头)set-cookie 头的信息存储到浏览器中set-cookie 头的数据,通过一个叫做 cookie 的请求头携带cookie 信息中 ID 吻合的 Session 对象request.getSession() 方法找到该 Session 对象@WebServlet("/sessionTest03")
public class SessionTest03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取 Session 对象
HttpSession session = request.getSession();
System.out.println(session);
// 期望浏览器关闭后, Session 对象也能相同
Cookie cookie = new Cookie("JSESSIONID", session.getId());
cookie.setMaxAge(60*60); // 设置存活时间为一个小时
response.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
当客户端不关闭,服务器关闭后,两次获取的 Session 对象不是同一个

\webapps 目录下,正常手动启动 Tomcat 服务器,项目就会被部署,正常手动关闭 Tomcat 服务器,Tomcat 服务器就会自动将 Session 对象序列化到硬盘上,在目录 work\Catalina\localhost 中(SESSIONS.ser 文件,里面存储的就是 Session 对象),一旦服务器被再次启动,文件将会被自动读取,该文件被删除掉,Session 对象就会被还原到内存中,虽然地址值不同,但是数据和 ID 值都保持与原来一致Session 对象的失效时间(销毁)
invalidate() 方法\conf\web.xml 文件中)<session-config>
<session-timeout>30session-timeout>
session-config>
需求:
login.jspsuccess.jsp,显示:用户名,欢迎您!分析:
success.jsp 页面login.jsp 页面中显示错误信息<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%= request.getAttribute("cc_error")==null?"":request.getAttribute("cc_error") %>
<%= request.getAttribute("login_error")==null?"":request.getAttribute("login_error") %>
@WebServlet("/checkCodeServlet")
public class CheckCodeServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int width=100;
int height=50;
// 创建一个对象,在内存中的验证码图片对象
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 美化图片
// 填充背景色
Graphics graphics = image.getGraphics(); // 画笔对象
graphics.setColor(Color.CYAN); // 设置画笔颜色
graphics.fillRect(0,0,width,height);
// 画边框
graphics.setColor(Color.BLUE);
graphics.drawRect(0,0,width-1,height-1);
// 写验证码
String str="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
// 生成随机角标
Random random = new Random();
StringBuilder stringBuilder=new StringBuilder();
for (int i = 1; i <= 4; i++) {
int index = random.nextInt(str.length());
// 获取字符,随机字符
char charAt = str.charAt(index);
stringBuilder.append(charAt);
graphics.drawString(charAt+"",width/5*i,height/2);
}
String checkCode_session = stringBuilder.toString();
// 将验证码存入 Session 达到共享数据的目的
request.getSession().setAttribute("checkCode_session",checkCode_session);
// 画干扰线
graphics.setColor(Color.pink);
// 随机生成坐标点
for (int i = 0; i < 10; i++) {
int x1 = random.nextInt(width);
int x2 = random.nextInt(width);
int y1 = random.nextInt(height);
int y2 = random.nextInt(height);
graphics.drawLine(x1,x2,y1,y2);
}
// 将图片输出到页面展示
ImageIO.write(image,"jpg",response.getOutputStream());
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置 Request 对象的编码
request.setCharacterEncoding("utf-8");
// 获取参数
String username = request.getParameter("username");
String password = request.getParameter("password");
String checkCode = request.getParameter("checkCode");
// 先获取生成的验证码
HttpSession session = request.getSession();
String checkCode_session = (String) session.getAttribute("checkCode_session");
// 删除 Session 中存储的验证码
session.removeAttribute("checkCode_session");
// 判断验证码是否正确
if (checkCode_session!=null&&checkCode_session.equalsIgnoreCase(checkCode)){
// 忽略大小写判断,比较字符串
// 如果验证码正确,判断用户名和密码是否一致
if ("张三".equals(username)&&"123".equals(password)){
// 此时需要调用 UserDao 查询数据库
// 登录成功
// 存储信息,用户信息
session.setAttribute("user",username); // 应该是存储 User 对象
// 重定向到 success.jsp
response.sendRedirect(request.getContextPath()+"/success.jsp");
}else {
// 登录失败
// 存储提示信息到 Request
request.setAttribute("login_error","用户名或密码错误!");
// 转发到登录界面
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
}else {
// 验证码不一致
// 存储提示信息到 Request
request.setAttribute("cc_error","验证码错误!");
// 转发到登录界面
request.getRequestDispatcher("/login.jsp").forward(request,response);
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%= request.getSession().getAttribute("user") %>,欢迎您!