一、会话概述
1、什么是会话
这里的会话,指的是web开发中的一次通话过程,当打开浏览器,访问网站地址后,会话开始,当关闭浏览器(或者到了过期时间),会话结束。
2、会话管理作用
什么时候会用到会话管理呢?最常见的就是购物车,当我们登录成功后,把商品加入到购物车之中,此时我们无论再浏览什么商品,当点击购物车时,那些加入的商品都仍在购物车中。
3、会话管理分类
在JavaEE的项目中,会话管理分为两类。分别是:客户端会话管理技术和服务端会话管理技术。
3.1、客户端会话管理技术
它是把要共享的数据保存到了客户端(也就是浏览器端)。每次请求时,把会话信息带到服务器,从而实现多次请求的数据共享。
3.2、服务端会话管理技术
它本质仍是采用客户端会话管理技术,只不过保存到客户端的是一个特殊的标识,并且把要共享的数据保存到了服务端的内存对象中。每次请求时,把这个标识带到服务器端,然后使用这个标识,找到对应的内存空间,从而实现数据共享。
二、客户端会话管理技术
1、什么是Cookie
它是客户端浏览器的缓存文件,里面记录了客户浏览器访问网站的一些内容。同时,也是HTTP协议请求和响应消息头的一部分(在HTTP协议课程中,我们备注了它很重要)。
2、Cookie的API详解
1、创建Cookie
方法名 作用 Cookie(String name,String value) 构造方法创建对象
// 演示Cookie的使用
//1.创建cookie,绑定数据key:value
Cookie cookie = new Cookie("sex","女孩?");
2、发送Cookie
//发送Cookie addCookie():向客户端添加Cookie resp.addCookie(cookie);
3、获取Cookie
返回值 方法名 说明 void addCookie(Cookie cookie) 向客户端添加Cookie Cookie[] getCookies() 获取所有的Cookie String getName() 获取Cookie名字 String getValue() 获取Cookie的值
//获取Cookie getCookies():获取所有的Cookie Cookie[] cookies = req.getCookies(); //遍历数组,拿出每个Cookie for (Cookie cookie1 : cookies) { //获取cookie名字 String name = cookie1.getName(); //获取cookie值 String value = cookie1.getValue(); System.out.println("name = "+ name +" "+ "values ="+value); }
3、cookie在浏览器中保存多长时间
1.默认情况下,当浏览器关闭后,Cookie数据被销毁
2.持久化存储 :
setMaxAge(int seconds)
正数::将Cookie数据写到硬盘的文件中。持久化存储。并指定cookie存活时间,时间到后,cookie文件自动失效
负数:默认值
零:删除cookie信息
//创建Cookie Cookie cookie = new Cookie("msg","女孩"); //setMaxAge(60*60):保存cookie一小时 cookie.setMaxAge(60*60);
4、cookie能不能存中文?
在tomcat 8 之前 cookie中不能直接存储中文数据。 需要将中文数据转码---一般采用URL编码(%E3)
在tomcat 8 之后,cookie支持中文数据。特殊字符还是不支持,建议使用URL编码存储,URL解码解析
5、cookie共享问题?
假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享?
默认情况下cookie不能共享
setPath(String path):设置cookie的获取范围。默认情况下,设置当前的虚拟目录
如果要共享,则可以将path设置为"/"
//创建Cookie Cookie cookie = new Cookie("msg","女孩"); //设置cookie共享范围 cookie.setPath("/");
注意:Cookie有大小,个数限制。每个网站最多只能存20个cookie,且大小不能超过4kb。同时,所有网站的cookie总数不超过300个。
三、HttpSession概述
1、HttpSession对象介绍
它是Servlet规范中提供的一个接口。该接口的实现由Servlet规范的实现提供商提供。我们使用的是Tomcat服务器,它对Servlet规范进行了实现,所以HttpSession接口的实现由Tomcat提供。该对象用于提供一种通过多个页面请求或访问网站来标识用户并存储有关该用户的信息的方法。简单说它就是一个服务端会话对象,用于存储用户的会话数据。
同时,它也是Servlet规范中四大域对象之一的会话域对象。并且它也是用于实现数据共享的。但它与我们之前讲解的应用域和请求域是有区别的。
域对象 作用范围 使用场景 ServletContext 整个应用范围 当前项目中需要数据共享时,可以使用此域对象。 ServletRequest 当前请求范围 在请求或者当前请求转发时需要数据共享可以使用此域对象。 HttpSession 会话返回 在当前会话范围中实现数据共享。它可以在多次请求中实现数据共享。
2、HttpSession的获取
返回值 方法名 说明 HttpSession getSession() 获取HttpSession对象
//获取session域 HttpSession session = req.getSession();
3、HttpSession的常用方法
返回值 方法名 说明 void setAttribute(String name,Object value) 设置共享数据 Object getAttribute(String name) 获取共享数据 void removeAttribute(String name) 移除共享数据 String getId() 获取唯一标识名称 void Invalidate() 让session立即销毁
3.1、存数据
//获取session域 HttpSession session = req.getSession(); //设置值 session.setAttribute("sex","女孩");
3.2、取数据
//获取值 Object sex = session.getAttribute("sex");
3.3、删除数据
//删除数据 session.removeAttribute("sex");
3.4、获得session的id
//获取session的id String id = session.getId();
3.5、销毁session
//销毁session session.invalidate();
四、HttpSession的原理
1、session的原理
HttpSession,它虽然是服务端会话管理技术的对象,但它本质仍是一个Cookie。是一个由服务器自动创建的特殊的Cookie,Cookie的名称就是JSESSIONID,Cookie的值是服务器分配的一个唯一的标识。
当我们使用HttpSession时,浏览器在没有禁用Cookie的情况下,都会把这个Cookie带到服务器端,然后根据唯一标识去查找对应的HttpSession对象,找到了,我们就可以直接使用了。
2、Session的细节
1、session什么时候被销毁?
1.服务器关闭 2.session对象调用invalidate() 。 3.session默认失效时间 30分钟
1、session用于存储一次会话的多次请求的数据,存在服务器
2、session可以存储任意类型,任意大小的数据
3、HttpSession的钝化和活化
1、什么是持久态
把长时间不用,但还不到过期时间的HttpSession进行序列化,写到磁盘上。
我们把HttpSession持久态也叫做钝化。(与钝化相反的,我们叫活化。)
2、什么时候使用持久化
第一种情况:当访问量很大时,服务器会根据getLastAccessTime来进行排序,对长时间不用,但是还没到过期时间的HttpSession进行持久化
第二种情况:当服务器进行重启的时候,为了保持客户HttpSession中的数据,也要对HttpSession进行持久化
注意:HttpSession的持久化由服务器来负责管理,我们不用关心。 只有实现了序列化接口的类才能被序列化,否则不行。
五、Cokie和session案例
记住上一次访问时间
1、 需求:
1、登录的时候需要验证码登录验证成功则判断是否是第一次访问如果是则在页面上显示欢迎第一次访问本网站,如果不是第一次访问则提示:欢迎,上次访问的时间是:显示时间字符串
2、登录验证失败则跳回登录页面
2、步骤:
1、验证码类:
package utils;
import javax.imageio.ImageIO;
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 java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
/**
* @author 86136
*/
@WebServlet("/checkCodeServlet")
public class CheckCodeServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int width = 100;
int height = 50;
//1.创建一对象,在内存中图片(验证码图片对象)
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//2.美化图片
//2.1 填充背景色
Graphics g = image.getGraphics();//画笔对象
g.setColor(Color.PINK);//设置画笔颜色
g.fillRect(0,0,width,height);
//2.2画边框
g.setColor(Color.BLUE);
g.drawRect(0,0,width - 1,height - 1);
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789";
//生成随机角标
Random ran = new Random();
//StringBuffer类,指可变字符序列,用于构造字符串对象。其内部使用自动扩容的数组来操作字符串数据
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 4; i++) {
int index = ran.nextInt(str.length());
//获取字符
char ch = str.charAt(index);//随机字符
sb.append(ch);
//2.3写验证码
g.drawString(ch+"",width/5*i,height/2);
}
String checkCode_session = sb.toString();
//将生成的验证码存入session
req.getSession().setAttribute("checkSession",checkCode_session);
//2.4画干扰线
g.setColor(Color.GREEN);
//随机生成坐标点
for (int i = 0; i < 10; i++) {
int x1 = ran.nextInt(width);
int x2 = ran.nextInt(width);
int y1 = ran.nextInt(height);
int y2 = ran.nextInt(height);
g.drawLine(x1,y1,x2,y2);
}
//3.将图片输出到页面展示
ImageIO.write(image,"jpg",resp.getOutputStream());
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
}
2、判断是否找到Cookie类
package utils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
/**
* @author 86136
*/
public class CookieUtils {
public static Cookie getCookie(HttpServletRequest res,String cookieName){
//1、通过请求获取所有Cookie
Cookie[] cookies = res.getCookies();
//2.判断该数组是否有值
if (cookies != null && cookies.length > 0){
//2、遍历获取所有cookie
for (Cookie cookie : cookies) {
String name = cookie.getName();
//判断当前cookie的name,是否是我们要找的
if (name.equals(cookieName)){
//如果是就将这个cookie返回
return cookie;
}
}
}
return null;
}
}
3、jsp页面
<%-- Created by IntelliJ IDEA. User: 86136 Date: 2024/6/4 Time: 16:01 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>验证码</title> </head> <body> <form method="post" action="/c"> 用户名:<input type="text" name="username"> <br> 密码:<input type="password" name="password"> <br> 验证码:<input type="text" name="check"> <img src="/checkCodeServlet" id="img"> <br> <input type="submit" value="提交"> </form> </body> <script> //点击切换图片,图片来自于后台服务器,重置src,即可重新发起请求,生成图片 window.οnlοad=function () { //1.获取图片对象 var img = document.getElementById("img"); //2.绑定单击事件 img.οnclick=function () { //使用时间戳作为参数,防止浏览器缓存 var time = new Date().getTime(); //重置src,浏览器缓存特性,短时间内,请求路径和参数不变时, 不会真正向后台发起请求 img.src = "/checkCodeServlet?time="+time; } } </script> </html>
4、实现类
package com;
import utils.CookieUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author 86136
*/
@WebServlet("/c")
public class Cookies03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置浏览器中文显示乱码问题
resp.setContentType("text/html;charset=utf-8");
//获取页面传入的验证码
String check = req.getParameter("check");
//获取session中存储的验证码
HttpSession session = req.getSession();
Object checkCode_session = session.getAttribute("checkSession");
//验证码是一次性的,获取后删除
session.removeAttribute("checkSession");
//类型转换
String s = String.valueOf(checkCode_session);
//判断验证码
if (check.equalsIgnoreCase(s)) {
//一样
//看cookie中有没有lastTime
Cookie lastTime = CookieUtils.getCookie(req, "lastTime");
//判断是否是第一次访问
if (lastTime == null){
//没有,说明第一次访问 记录这次访问时间
lastTime(resp);
//返回数据
resp.getWriter().write("欢迎第一次访问本网站");
}else {
//有,说明之前访问过
//获取上次访问时间的值
String value = lastTime.getValue();
//记录这次访问的时间
lastTime(resp);
resp.getWriter().write("欢迎,上次访问的时间是:"+value);
}
}else {
System.out.println("验证码错误");
resp.sendRedirect("http://localhost:8080/");
}
}
public void lastTime(HttpServletResponse resp) throws UnsupportedEncodingException {
//获取当前时间
Date date = new Date();
//设置当前时间格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
String format = simpleDateFormat.format(date);
//创建cookie 保存当前时间
Cookie cookie = new Cookie("lastTime",format);
//添加进cookie
resp.addCookie(cookie);
}
}
标签:String,session,cookie,Cookie,import,HttpSession From: https://blog.csdn.net/qq_64011014/article/details/139451793