1 基本知识
1.1 什么会话?
在 BS 架构的应用中,浏览器需要向服务器发起请求,服务器从发起请求开始,其实就建立起了会话,而一个浏览器可以与这个服务器发起多次请求,多次请求都是属于一个会话的。即会话技术是用于保存一些特定的信息,跟踪浏览器与服务器的请求,使得可以在多次请求间共享数据。
1.2 会话技术分类
会话技术主要有两种,一种是 cookie,一种是 session。其中 cookie 是面向浏览器的,信息存储客户端。session 是面向服务端的,数据存储在服务端。
1.3 cookie 详细
1.3.1 cookie 的基本原理
cookie 实际上是基于 http 协议的,http 请求头和响应头中有响应的 cookie 数据。服务端可以发送 cookie 到浏览器,浏览器会将 cookie 存储,在另一次请求中,浏览器会将本地存储的 cookie 发送到服务器,服务器可以获取 cookie 进行一定的处理。
1.3.2 cookie 的存活时间
Cookie 在默认情况下是存储在内存中的,即当浏览器重启之后,之前请求所获得的 cookie 将不再存在。在某些情况下,我们期望在一定的时间内保存 cookie,即将 cookie 存储在本地,比如登录某个网站,设置七天免登录(如学校的智慧理工系统)。
可以调用 API 设置相应的时间:setMaxAge(int seconds),具体:
1)正数:将 cookie 写入浏览器所在的硬盘中,持久化存储
2)负数:默认值,即将 cookie 存储在内存中,关闭浏览器的时候释放。
3)零:删除对应的 cookie
1.3.3 cookie 存储中文
需要进行 URL 编码,即服务端发送 cookie 的时候进行 URL 编码,服务端接收 cookie 的时候进行 URL 解码。
1.4 session 简介
1.4.1 session 的基本原理
session 底层是基于 cookie 实现的,每一个 session 也是对一次会话进行标记,可以存储一次会话中的信息,用于在各个请求之间传递数据,而 session 是存储在服务器上面的,如何保证多次请求,服务器能知道是一次会话的内容呢?其实利用了 cookie,每次创建一个 session,就会创建一个唯一的 sessionID,唯一的表示 session,而这个 sessionID 的存储方式就是 cookie。
1.4.2 session 的钝化和活化
session 存储在服务端,就可能存在一种场景,很可能服务器会重新启动,这样若一次会话始于重启之前,重启之后继续访问,那 session 的值该如何变化呢?
1)钝化:在服务器关闭的时候,内存中的 session 会被存储在本地磁盘中
2)活化:如果本地有 session,那么会将这个 session 的文件读取并存入内存中,并删除该文件,使得 session 得以恢复
1.4.3 session 的销毁
session 在存储一段时间后,会存在自动销毁:
1)Tomcat 服务器有默认的销毁时间:30 分钟
<session-config>
<session-timeout>30</session-timoe>
</session-config>
2)可以自己在 web.xml 文件中配置自动销毁的时间
<session-config>
<session-timeout>时间(单位分钟)</session-timoe>
</session-config>
3)调用方法直接销毁:invalidate()
2 代码实践
2.1 cookie 基本使用
1)设置 cookie
package cn.edu.njust.cookiesession;
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;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
/**
* cookie的基本使用
*/
@WebServlet("/cookie01")
public class CookieDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.创建cookie对象
Cookie cookie = new Cookie("username", "test");
// 为username设置存活时间:7天
cookie.setMaxAge(7 * 24 * 60 * 60);
// 2.发送cookie
resp.addCookie(cookie);
/*
* 中文编码
* */
String value = "张山";
value = URLEncoder.encode(value, StandardCharsets.UTF_8);
// 设置cookie
Cookie cookie1 = new Cookie("name", value);
// 发送cookie
resp.addCookie(cookie1);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
2)获取 cookie
package cn.edu.njust.cookiesession;
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;
import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
/**
* cookie的基本使用
*/
@WebServlet("/cookie02")
public class CookieDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.获取cookie
Cookie[] cookies = req.getCookies();
// 2.遍历处理自己需要的cookie
for (Cookie cookie : cookies) {
String name = cookie.getName();
if ("username".equals(name)) {
System.out.println(name + ":" + cookie.getValue());
}
if ("name".equals(name)) {
// 解析中文
String value = URLDecoder.decode(cookie.getValue(), StandardCharsets.UTF_8);
System.out.println(name + ":" + value);
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
2.2 session 的基本使用
1)设置 session
package cn.edu.njust.cookiesession;
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 java.io.IOException;
@WebServlet("/session01")
public class SessionDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.获取session
HttpSession session = req.getSession();
// 设置名称
String name = "session1";
// 2.存储session,参数:键,值
session.setAttribute("sessionName", name);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
2)获取 session
package cn.edu.njust.cookiesession;
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 java.io.IOException;
@WebServlet("/session02")
public class SessionDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.获取session
HttpSession session = req.getSession();
// 2.获取session的值
String sessionName = (String) session.getAttribute("sessionName");
System.out.println(sessionName);
// 3.根据键删除该session键值对
session.removeAttribute(sessionName);
// 4.销毁session
// session.invalidate();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
3 方法汇总
3.1 cookie 常用 API
**方法原型 ** | 说明 |
---|---|
void addCookie(Cookie var1) | 添加 cookie,发送到浏览器 |
public void setMaxAge(int expiry) | 设置 cookie 的存活时间 |
public static String encode(String s, Charset charset) | 中文进行 URL 编码 |
public static String decode(String s, Charset charset) | 对 URL 编码进行解码 |
Cookie[] getCookies() | 获取所有的 cookie |
public String getName() | 获取 cookie 的键 |
public String getValue() | 获取 cookie 的值 |
3.2 session 常用 API
**方法原型 ** | 说明 |
---|---|
HttpSession getSession() | 获取 session |
void setAttribute(String var1, Object var2) | 设置 session 的值 |
Object getAttribute(String var1) | 根据键获取 session 的值 |
void removeAttribute(String var1) | 根据键的值,删除 session 键值对 |
void invalidate() | 销毁该 session |