Cookie&Session
会话跟踪技术
HTTP协议是无状态的,每次浏览器向服务器请求时,服务器都会将该请求视为新的请求,因此我们需要会话跟踪技术来实现会话内数据共享。
会话
用户打开浏览器,访问web服务器的资源,会建立会话,直到一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。
会话跟踪
一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据。
实现方式
- 客户端会话跟踪技术:Cookie
- 服务端会话跟踪技术:Session
Cookie
客户端会话技术,将数据保存到客户端,以后每次请求都携带着Cookie数据进行访问。主要使用在一次会话的多次请求中。
基本使用
📕 发送Cookie
-
创建Cookie对象, 设置数据
Cookie cookie = new Cookie("key", "value");
-
发送Cookie到客户端,使用response对象
response.addCookie(cookie);
📕 获取Cookie
-
获取域中的所有Cookie
Cookie[] cookie = request.getCookies();
-
遍历Cookie, 获取每一个Cookie对象
for(int i = 0; i < cookie.length; i++){ if(/*添加获取相应cookie的条件*/){ //执行操作 } }
-
使用Cookie对象方法获取数据
cookie.getName(); cookie.getValue();
📕 修改Cookie
-
方案一
①创建一个修改的同名(key)的cookie对象
②在构造器中同时赋予新的cookie值
③调用respinse.addCookie(cookie),将原来的cookie修改 -
方案二
①先查找需要修改的Cookie对象
static Cookie findCookie(Cookie[] cookies, String name){ if(name == null || cookies.length == 0){ return null; } for(Cookie cookie:cookies){ if(cookie.getName().equals(name)){ return cookie; } } return null; }
②调用setValue()方法赋予新的Cookie值
③调用response.addCookie(cookie对象)通知客户端保存对象
Cookie原理
Cookie的实现是基于HTTP协议的
响应头:set-cookie
请求头:cookie
Cookie使用细节
Cookie存活时间
默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁
我们也可以使用setMaxAge(int seconds)改变存活时间。
int seconds | 含义 |
---|---|
正数 | 表示在指定的秒数后销毁 |
负数 | 表示在浏览器关闭的时候Cookie就被删除,默认是-1 |
0 | 表示立马删除 |
Cookie存储中文
Cookie不能直接存储中文,如果需要存储则需要进行转码。
//URL编码
URLEncoder.encode(目标对象,"UTF-8")
//URL解码
URLDecoder.decode(目标对象,"UTF-8")
//如:
URLEncoder.encode("路易斯基", "utf-8")
URLDecoder.decode(cookies[i].getValue(), "utf-8")
示例
package cookie;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
* @author XRY
* @date 2023年05月06日9:05
*/
//中文数据传递
public class TestCookie01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html; charset = UTF-8");
Cookie[] cookies = req.getCookies();
if(cookies != null){
resp.getWriter().write("上次访问是:");
for(int i = 0; i < cookies.length; i++){
if(cookies[i].getName().equals("name")){
resp.getWriter().write(URLDecoder.decode(cookies[i].getValue(), "utf-8"));
}
}
}
Cookie cookie = new Cookie("name", URLEncoder.encode("路易斯基", "utf-8"));
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
示例
package cookie;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
/**
* @author XRY
* @date 2023年05月04日8:46
*/
//保存用户上一次访问的时间
public class TestCookie extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//服务器:告诉你你来的时间,把这个时间封装成一个信件,下次带来
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html; charset=UTF-8");
PrintWriter out = resp.getWriter();
//Cookie,服务器从客户端获取
Cookie[] cookies = req.getCookies();//返回值为数组,说明cookie可能存在多个
//判断cookie是否存在
if(cookies != null){
//如果存在
out.write("你上一次访问的时间是:");
// for (Cookie cookie : cookies) {
//
// }
for(int i = 0; i < cookies.length; i++){
Cookie cookie = cookies[i];
if(cookie.getName().equals("LastTime")){
//获取cookie中的值
String value = cookie.getValue();//当前得到的是一个字符串,我们需要的是date类型
//将字符串解析为长整形
long LastTime = Long.parseLong(value);
Date date = new Date(LastTime);
out.write(date.toLocaleString());
}
}
}else{
out.write("这是你第一次访问本站");
}
//服务器给客户端响应一个cookie
//在Cookie类中 public Cookie(String name, String value),只能够存String类型,所以可以使用String.valueOf
Cookie cookie = new Cookie("LastTime", String.valueOf(System.currentTimeMillis()));
//设置有效期
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
Session
服务端会话跟踪技术,将数据保存到服务端。服务器会为每一个用户(浏览器)创建一个Session对象。一个Session独占一个浏览器,只要浏览器不关闭,这个Session就存在。用户登录后,整个网站都可以访问。例如:保存购物车的信息,
Session是基于Cookie实现的。
基本使用
-
获取Session对象
HttpSession session = request.getSession();
-
Session对象功能
setAttribute(String name, Object o);将数据存储到Session中 Object getAttribute(String name);根据key获得值 removeAttribute(String name);根据key, 删除该键值对
-
使用细节
-
Session钝化、活化
钝化:在服务器正常关闭后,Tomcat会自动将Session数据写入硬盘文件中
活化:再次启动服务器后,从文件中加载数据到Session中
-
Session销毁
1、默认情况下,30分钟自动销毁
2、调用Session对象的invalidate()方法package session; import javax.servlet.ServletException; import javax.servlet.http.*; import java.io.IOException; /** * @author XRY * @date 2023年05月07日17:42 */ public class Session01 extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //解决乱码问题 req.setCharacterEncoding("utf-8"); resp.setContentType("text/html; charset=UTF-8"); //得到session HttpSession session = req.getSession(); //给session存入东西 session.setAttribute("name", "路易斯基"); //获得session的ID String id = session.getId(); //判断session是不是新创建的 if(session.isNew()){ resp.getWriter().write("session创建成功, ID为" + id); }else{ resp.getWriter().write("session已经在服务器中存在了" + id); } //Session创建的时候做了什么事情 /*Cookie cookie= new Cookie("JSESSIONID", id); resp.addCookie(cookie);*/ } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
//手动注销session package session; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; @WebServlet("/Session03") public class Session03 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); session.removeAttribute("name"); //手动注销session session.invalidate(); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } } //自动注销session 在web.xml文件中设置 <!-- 设置Session默认的失效时间--> <session-config> <!-- 表示12分钟后session自动失效,以分钟为单位--> <session-timeout>12</session-timeout> </session-config>
-
-
Session使用场景
保存登录用户的信息
购物车信息
在整个网站中经常会使用的数据,我们将它保存在Session中
Cookie和Session之间的异同
Cookie和Session都是来完成一次会话内多次请求间数据共享的。
区别
1、存储位置:Cookie是将数据存储在客户端,Session是将数据存储在服务器
2、安全性:Cookie不安全,Session安全
3、数据大小:Cookie最大3kb,Session无大小限制
4、存储时间:Cookie可以长期存储,Session默认30分钟
5、服务器性能:Cookie不占用服务器资源,Session占用服务器资源。