会话技术
会话
- 一次会话中包含多次请求和响应
- 一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止
功能
- 在一次会话的范围内的多次请求间,共享数据
方式
- 客户端会话技术:Cookie
- 服务器端会话技术:Session
Cookie
概念:客户端会话技术,将数据保存到客户端
使用步骤
- 创建Cookie对象,绑定数据:
new Cookie(String name, String value)
- 发送Cookie对象:
response.addCookie(Cookie cookie)
- 获取Cookie,拿到数据:
Cookie[] request.getCookies()
@WebServlet("/cookieDemo1")
public class CookieDemo1 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.创建 Cookie 对象
Cookie c = new Cookie("msg", "hello");
// 2.发送 Cookie
response.addCookie(c);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}
}
@WebServlet("/cookieDemo2")
public class CookieDemo2 extends HttpServlet {
@Override
protected void doPost(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); // msg:hello
}
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}
}
实现原理
- 基于响应头
set-cookie
和请求头cookie
实现 - response 给浏览器发送响应头
set-cookie:msg=hello
- 浏览器将发送的
msg=hello
保存到客户端浏览器中 - 当浏览器再次请求时,
msg=hello
被放在请求头cookie中cookie:msg=hello
发送给服务器
Cookie的细节
一次可以发送多个Cookie
- 可以创建多个Cookie对象,使用response调用多次
addCookie()
方法发送Cookie即可
Cookie在浏览器中保存时间
- 默认情况下,当浏览器关闭后,Cookie数据被销毁
- 持久化存储:
setMaxAge(int seconds)
- 正数:将Cookie数据写到硬盘的文件中,持久化存储。并指定Cookie存活时间(时间到后,Cookie文件自动失效)
- 负数:默认值
- 零:删除Cookie信息
@WebServlet("/cookieDemo1")
public class CookieDemo3 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.创建 Cookie 对象
Cookie c = new Cookie("msg", "hello");
// 2.设置cookie的存活时间
c.setMaxAge(30); // 将cookie持久化到硬盘,30秒后会自动删除cookie文件
//c.setMaxAge(-1); // 负数:默认值,关闭浏览器就删除
//c.setMaxAge(0); // 零:删除cookie信息
// 3.发送 Cookie
response.addCookie(c);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}
}
Cookie中文问题
- 在 tomcat 8 之前Cookie中不能直接存储中文数据,需要将中文数据转码(一般采用URL编码)
- 在 tomcat 8 之后,Cookie支持中文数据。特殊字符还是不支持,建议使用URL编码存储,URL解码解析
Cookie获取范围(共享问题)
-
在一个tomcat服务器中,部署了多个web项目,那么这些web项目中Cookie的共享问题
- 默认情况下不共享
setPath(String path)
:设置cookie的获取范围。默认情况下,设置当前的虚拟目录
-
如果要共享,则可以将path设置为
“/”
-
不同的tomcat服务器Cookie共享问题
setDomain(String path)
:如果设置一级域名相同,那么多个服务器之间Cookie可以共享setDomain(".baidu.com")
,那么tieba.baidu.com
和news.baidu.com
中Cookie可以共享
Cookie的特点
- Cookie存储的数据在客户端浏览器
- 浏览器对于单个Cookie的大小有限制(4kb),对于同一个域名下的总Cookie数量也有限制(20个)
Cookie的作用
- Cookie一般用于存储少量的不太敏感的数据
- 在不登录的情况下,完成服务器对客户端的身份识别
Session
概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中(HtppSession)
HttpSession对象
-
获取HttpSession对象:
HttpSession session = request.getSession();
-
使用HttpSession对象
Object getAttribute(String name)
void setAttribute(String name, Object value)
void removeAttribute(String name)
@WebServlet("/sessionDemo1")
public class SessionDemo1 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 使用Session共享数据
// 1.获取session
HttpSession session = request.getSession();
// 2.存储数据
session.setAttribute("msg","hello");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}
}
@WebServlet("/sessionDemo2")
public class SessionDemo2 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 使用 Session 获取数据
// 1.获取 Session
HttpSession session = request.getSession();
// 2.获取数据
Object msg = session.getAttribute("msg");
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}
}
原理
- Session的实现是依赖于Cookie的。
- 服务器如何确保在一次会话范围内,多次获取的Session对象是同一个
- 第一次获取Session,没有Cookie,会在内存中创建一个新的Session对象(有唯一的id)
- 给服务器做响应的时候会发送
set-cookie:JSESSIONID=id
存储到浏览器中 - 当再次访问当前项目的其他资源时会带着请求头
cookie
细节
-
当客户端关闭后,服务器不关闭,两次获取Session是否为同一个
- 默认情况下:不是
- 如果需要相同,则可以创建Cookie,键为
JSESSIONID
,设置最大存活时间,让Cookie持久化保存。
// 获取Session HttpSession session = request.getSession(); // 期望客户端关闭后,Session也能相同 Cookie c = new Cookie("JSESSIONID",session.getId()); c.setMaxAge(60*60); // 1小时 response.addCookie(c);
-
客户端不关闭,服务器关闭后,两次获取的Session是否为同一个
- 不是同一个,但是要确保数据不丢失。
- tomcat本地自动完成以下工作
- Session的钝化:在服务器正常关闭之前,将Session对象系列化到硬盘上
- Session的活化:在服务器启动后,将Session文件转化为内存中的Session对象即可
-
Session什么时候被销毁
- 服务器关闭
- Session对象调用
invalidate()
自己销毁自己 - Session默认失效时间 30分钟
<!-- 选择性配置修改 --> <session-config> <session-timeout>30</session-timeout> </session-config>
Session的特点
- Session用于存储一次会话的多次请求的数据,存在服务器端
- Session可以存储任意类型,任意大小的数据
session与Cookie的区别
- Session存储数据在服务器端,Cookie在客户端
- Session没有数据大小限制,Cookie有
- Session数据安全,Cookie相对于不安全