目录
会话技术是什么?
HTTP(超文本传输协议)是一个基于请求与响应模式的无状态协议。
由于 HTTP 协议是无协议的,无法保存和跟踪用户状态,所以需要其他的方案来解决问此题,它就是会话技术。
从打开浏览器访问某个网站,到关闭浏览器的过程,称为一次会话 。
会话技术是指在会话中,帮助服务器记录用户状态和数据的技术。
常用的会话技术分为两种:
Cookie :客户端会话技术
Session :服务端会话技术
Cookie是什么?
Cookie 属于客户端会话技术,它是服务器发送给浏览器的小段文本信息,存储在客户端浏览器的内存中或硬盘上。
当浏览器保存了 Cookie 后,每次访问服务器,都会在 HTTP 请求头中将这个 Cookie 回传给服务器。
Cookie 的分类:
会话级别 Cookie(默认):Cookie 保存到浏览器的内存中,浏览器关闭则 Cookie 失效。
持久的 Cookie:Cookie 以文本文件的形式保存到客户端硬盘上。
Cookie 的工作流程?
客户端浏览器访问服务器时,服务器通过在 HTTP 响应中增加 Set-Cookie 字段,将数据信息发送给浏览器。
浏览器将 Cookie 保存在内存中或硬盘上。
再次请求该服务器时,浏览器通过在 HTTP 请求消息中增加 Cookie 请求头字段,将 Cookie 回传给 Web 服务器。服务器根据 Cookie 信息跟踪客户端的状态。
Cookie API?
javax.servlet.http 包中定义了一个 Cookie 类,利用它的带参构造方法,可以创建 Cookie 对象
Cookie cookie=new Cookie("name","user1");
HttpServletResponse 接口和 HttpServletRequest 接口也都定义了与 Cookie 相关的方法:
方法 | 描述 | 所属接口 |
---|---|---|
void addCookie(Cookie cookie) | 用于在响应头中增加一个相应的 Set-Cookie 头字段。 | javax.servlet.http.HttpServletResponse |
Cookie[] getCookies() | 用于获取客户端提交的 Cookie。 | javax.servlet.http.HttpServletRequest |
javax.servlet.http.Cookie 类中提供了一系列获取或者设置 Cookie 的方法 :
返回值类型 | 方法 | 描述 |
---|---|---|
int | getMaxAge() | 用于获取指定 Cookie 的最大有效时间,以秒为单位。 默认情况下取值为 -1,表示该 Cookie 保留到浏览器关闭为止。 |
String | getName() | 用于获取 Cookie 的名称。 |
String | getPath() | 用于获取 Cookie 的有效路径。 |
boolean | getSecure() | 如果浏览器只通过安全协议发送 Cookie,则返回 true;如果浏览器可以使用任何协议发送 Cookie,则返回 false。 |
String | getValue() | 用于获取 Cookie 的值。 |
int | getVersion() | 用于获取 Cookie 遵守的协议版本。 |
void | setMaxAge(int expiry) | 用于设置 Cookie 的最大有效时间,以秒为单位。 取值为正值时,表示 Cookie 在经过指定时间后过期。取值为负值时,表示 Cookie 不会被持久存储,在 Web 浏览器退出时删除。取值为 0 时,表示删除该 Cookie。 |
void | setPath(String uri) | 用于指定 Cookie 的路径。 |
void | setSecure(boolean flag) | 用于设置浏览器是否只能使用安全协议(如 HTTPS 或 SSL)发送 Cookie。 |
void | setValue(String newValue) | 用于设置 Cookie 的值。 |
实例:
生成Cookie:
package com.m0_54698212.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "CookieServlet", value = "/cookie")
public class CookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//服务器生成cookie信息:set-cookie指令
//不能存对象,存字符串
//默认会话级cookie,关闭浏览器就没了
Cookie cookie1 = new Cookie("user1","lalala");
Cookie cookie2 = new Cookie("user2", "哈哈哈");
// 设置cookie的存活时间:5min,持久化cookie,会保存到客户端电脑,文本文件
cookie2.setMaxAge(300);
//通过响应对象向客户端响应
response.addCookie(cookie1);
response.addCookie(cookie2);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
获取Cookie:
package com.m0_54698212.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "GetCookieServlet", value = "/getCookie")
public class GetCookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=utf-8");
PrintWriter out = response.getWriter();
//获取cookie,请求,cookie随着客户端浏览器请求过来
Cookie[] cookies = request.getCookies();
if (cookies!= null) {
for (Cookie cookie : cookies) {
out.println("获取成功" + cookie.getName() + " : " + cookie.getValue());
System.out.println(cookie.getName() + " : " + cookie.getValue());
}
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
index.jsp:
<%--指令:用来配置整个页面的属性--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Cookie</title>
</head>
<body>
<ul>
<li><a href="/cookie">获取cookie</a></li>
<li><a href="/getCookie">生成cookie</a></li>
<li><div>获取cookie:${cookie.user1.value}----${cookie.user2.value}</div></li>
</ul>
</body>
</html>
运行结果:
点击获取cookie:
点击生成cookie:
Session是什么?
Session 是服务器端会话技术。当浏览器访问 Web 服务器的资源时,服务器可以为每个用户浏览器创建一个 Session 对象,每个浏览器独占一个 Session 对象。
Session 的工作原理?
当客户端第一次请求会话对象时,服务器会创建一个 Session 对象,并为该 Session 对象分配一个唯一的 SessionID(用来标识这个 Session 对象);
服务器将 SessionID 以 Cookie(Cookie 名称为:“JSESSIONID”,值为 SessionID 的值)的形式发送给客户端浏览器;
客户端浏览器再次发送 HTTP 请求时,会将携带 SessionID 的 Cookie 随请求一起发送给服务器;
服务器从请求中读取 SessionID,然后根据 SessionID 找到对应的 Session 对象。
Session什么时候创建?
在servlet中手动调用
HttpSession session = request.getSession(); 或者 HttpSession session = request.getSession(true)
jsp中有写<%@ page session="true"%>
Session API:
Session 对象由服务器创建,通过 HttpServletRequest.getSession() 方法可以获得 HttpSession 对象
HttpSession session=request.getSession();
HttpSession 接口定义了一系列对 Session 对象操作的方法:
返回值类型 | 方法 | 描述 |
---|---|---|
long | getCreationTime() | 返回创建 Session 的时间。 |
String | getId() | 返回获取 Seesion 的唯一的 ID。 |
long | getLastAccessedTime() | 返回客户端上一次发送与此 Session 关联的请求的时间。 |
int | getMaxInactiveInterval() | 返回在无任何操作的情况下,Session 失效的时间,以秒为单位。 |
ServletContext | getServletContext() | 返回 Session 所属的 ServletContext 对象。 |
void | invalidate() | 使 Session 失效。 |
void | setMaxInactiveInterval(int interval) | 指定在无任何操作的情况下,Session 失效的时间,以秒为单位。负数表示 Session 永远不会失效。 |
设置 Session 过期时间两种方式:
Session 的默认过期时间为 30 分钟,可以通过如下两种方式设置过期时间:
- 使用 <session-config> 元素
- 调用 setMaxInactiveInterval() 方法
实例:
package com.m0_54698212.servlet;
import com.m0_54698212.entity.Emp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "SessionServlet", value = "/session")
public class SessionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//HttpSession session=request.getSession(true);
HttpSession session=request.getSession();
session.setMaxInactiveInterval(10);
session.setAttribute("name","dadada");
session.setAttribute("emp",new Emp("哈哈哈"));
response.sendRedirect("/");//"/index.jsp";
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
Session 的生命周期?
Session 对象创建:
Session 对象在容器第一次调用 request.getSession() 方法时创建。
Session 对象销毁:
Session 对象在如下 3 种情况下会被销毁:
Session 过期;
调用 session.invalidate() 方法,手动销毁 Session;
服务器关闭或者应用被卸载。
实例:
package com.m0_54698212.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "SessionInvalidateServlet", value = "/sessionInvalidate")
public class SessionInvalidateServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getSession().invalidate();
response.sendRedirect(request.getContextPath() + "/");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
运行结果:
点击生成session:
点击session失效:
常用方法:
在 javax.servlet.http.HttpSession 接口中定义了一系列操作属性的方法:
返回值类型 | 方法 | 描述 |
---|---|---|
void | setAttribute(String name, Object o) | 把一个 Java 对象与一个属性名绑定,并将它作为一个属性存放到 Session 对象中。 参数 name 为属性名,参数 object 为属性值。 |
Object | getAttribute(String name) | 根据指定的属性名 name,返回 Session 对象中对应的属性值。 |
void | removeAttribute(String name) | 从 Session 对象中移除属性名为 name 的属性。 |
Enumeration | getAttributeNames() | 用于返回 Session 对象中的所有属性名的枚举集合。 |
实例:
package com.m0_54698212.servlet;
import com.m0_54698212.entity.Emp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "GetSessionServlet", value = "/getSession")
public class GetSessionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
String name = (String) session.getAttribute("name");
Emp emp = (Emp) session.getAttribute("emp");
response.getWriter().write((name+"---"+emp.getEname()));
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
运行结果:
点击生成session:
点击获取session:
Session域对象是什么?
Session 、request 以及 ServletContext 合称为 Servlet 的三大域对象,它们都能保存和传递数据
区别:
不同 | request | Session | ServletContext |
---|---|---|---|
类型 | javax.servlet.http.HttpServletRequest | javax.servlet.http.HttpSession | javax.servlet.ServletContext |
创建 | 客户端向容器发送请求时创建。 | 容器第一次调用 getSession() 方法时创建。 | Servlet 容器启动时创建。 |
销毁 | 容器对这次请求做出响应后销毁。 | Session 销毁的时机: 关闭服务器或应用被卸载。Session 过期,默认为 30 分钟。手动调用 session.invalidate() 方法进行销毁。 | 容器关闭或者 Web 应用被移除时销毁。 |
有效范围 | 只对当前请求涉及的 Servlet 有效。 | Session 对本次会话期间的所有 Servlet 都有效。 | 对整个 Web 应用内的所有 Servlet 有效。 |
数量 | Web 应用中的所有 Servlet 实例都可以有多个 request 对象。 | Web 应用中可以有多个 Session,多个 Servet 实例可以共享同一 Session 对象。 | 在整个 Web 应用中只有一个 Context 对象。 |
数据共享 | 每一次请求都是一个新的 request 对象。 通过和请求转发的配合使用可以实现一次请求中 Web 组件之间共享的数据。 | 每一次会话都是一个新的 Session 对象。 通过 Session 域对象可以实现一次会话中的多个请求之间共享数据。 | 在一个应用中有且只有一个 Context 对象,作用于整个 Web 应用,可以实现多次会话之间的数据共享。 |