1. 什么是会话
是指浏览器和服务端之间的数据传输(用户登录,购物车等)
会话管理就是管理浏览器和服务端会话过程产生的会话数据
常用的会话技术:
数据保存在浏览器的Cookie技术
数据保存在服务端的Session技术
2. Cookie技术
1. 什么是Cookie
Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器,当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是各自用户自己的数据了
2. Cookie技术核心API
Cookie类:用于存储会话数据,常用方法如下:
- 构造Cookie对象
Cookie(String name,String value)
- 设置cookie
void setPath(String uri):设置cookie的有效访问路径
void setMaxAge(int expiry):设置cookie的有效时间
void setValue(String newValue):设置cookie的值
- 发送cookie到浏览器保存
void response.addCookie(Cookie cookie):发送cookie
- 服务器端接收cookie
Cookie[] request.getCookies():接收cookie
Demo:
public class CookieDemo extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1.创建Cookie对象
Cookie cookie = new Cookie("name", "value");
// 2.设置Cookie参数
// 2.1设置Cookie的有效路径
cookie.setPath("/hello");// 默认就是web项目的地址
// 2.2设置Cookie的有效时间
cookie.setMaxAge(20);// 此cookie只存活20秒,从最后不调此cookie开始计算
cookie.setMaxAge(-1);// 此cookie保存在浏览器内存中,关闭浏览器则销毁此cookie
cookie.setMaxAge(0);// 删除与此cookie同名的cookie
// 3.把数据发送到浏览器
response.addCookie(cookie);
// 4.服务端接收来自浏览器的cookie
// 方法一:
// String name=request.getHeader("cookie");
// System.out.println(name);
// 方法二:
Cookie[] cookies = request.getCookies();
for (Cookie c : cookies) {
String name = c.getName();
String value = c.getValue();
System.out.println(name + "=" + value);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
3. Cookie原理
- 服务器创建Cookie对象,把会话数据存储到Cookie对象中
new Cookie("name","value");
- 服务器发送cookie信息到浏览器
response.addCookie(cookie);//其实是隐藏发送了一个set-cookie名称的响应头
- 浏览器得到服务器发送的cookie,然后保存在浏览器端
- 浏览器下次访问服务器时,会带着cookie信息
包含在http的请求头里
- 服务器接收到浏览器带来的cookie信息
request.getCookies();
4.Cookie的细节
- void setPath(String uri):设置cookie的有效访问路径,有效访问路径指的是Cookie的有效路径保存在哪里,那么浏览器在有效路径下访问服务器时就会带着Cookie信息,否则不带Cookie信息,默认是在当前web项目的路径下
void setMaxAge(int expiry):设置cookie的有效时间
expiry可以是正整数,负整数和零
正整数:表示Cookie数据保存浏览器的缓存到硬盘中,数值表示保存的时间
负整数:表示Cookie数据保存到浏览器的内存中,浏览器关闭Cookie就丢失了
零:表示删除同名的Cookie数据
- Cookie数据类型只能保存非中文字符串类型的。可以保存多个Cookie,但是浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4kb
5. Cookie应用:显示用户上次访问的时间
功能实现逻辑:
把时间保存在Cookie中,每次访问从Cookie里面调用
第一次访问:
1. 获取当前时间,显示到浏览器上
2. 创建Cookie对象,时间作为cookie值,名为:lastTime
3. 把cookie发送到浏览器保存
第n次访问:
1. 获取cookie的数据,取出名为lastTime的cookie
2. 得到cookie的值(上次访问时间)
3. 显示上次访问时间到浏览器上
4. 更新名为lastTime的cookie,值设置为当前时间
5. 把更新后的cookie发送给浏览器保存
代码实现:
public class CookieDemo2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
// 获取当前时间
SimpleDateFormat t = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String curTime = t.format(new Date());
// 取得cookie
Cookie[] cookies = request.getCookies();
String lastTime = null;
// 第n次访问
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("lastTime")) {
// 有lastTime的cookie,已经是第n次访问
lastTime = cookie.getValue();//上次访问的时间
// 第n次访问
// 1.把上次访问时间显示到浏览器上
response.getWriter().write(
"欢迎回来,你上次访问的时间是: " + lastTime + ",当前时间为: "+ curTime);
// 2.更新cookie
cookie.setValue(curTime);
cookie.setMaxAge(1 * 30 * 24 * 60 * 60);
// 3.把更新后的cookie发送到浏览器
response.addCookie(cookie);
break;
}
}
}
// 第一次访问 没有cookie 或有cookie但没有名为lastTime的cookie
if (cookies == null || lastTime == null) {
// 1.显示当前时间到浏览器上
response.getWriter().write("你是首次访问本网站,当前时间是: " + curTime);
// 2.创建Cookie对象
Cookie cookie = new Cookie("lastTime", curTime);
cookie.setMaxAge(1 * 30 * 24 * 60 * 60);
// 3.把cookie发送到浏览器保存
response.addCookie(cookie);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
6. Cookie应用:查看用户浏览过的商品
功能实现逻辑:
代码实现:
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map.Entry;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ListServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
// 显示商品列表
out.write("书籍列表: <br/>");
for (Entry<String, Book> b : Db.getBooks().entrySet()) {
out.write("<a href='" + request.getContextPath()
+ "/servlet/detailServlet?id=" + b.getKey()
+ "' target='_blank'>" + b.getValue().getName()
+ "</a><br/>");
}
// 显示浏览过的商品
out.write("<br/>浏览过的 : <br/>");
Cookie[] cookies = request.getCookies();
for (int i = 0; cookies != null && i < cookies.length; i++) {
if (cookies[i].getName().equals("history")) {
String[] ids = cookies[i].getValue().split("\\-");
for (String s : ids) {
out.write(Db.getBooks().get(s).getName() + "<br/>");
}
}
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Map.Entry;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DetailServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
// 显示商品详情
out.write("书籍详情: <br/>");
String id = request.getParameter("id");
for (Entry<String, Book> b : Db.getBooks().entrySet()) {
if (id.equals(b.getKey())) {
out.write(b.getValue().getId() + "<br/>");
out.write(b.getValue().getName() + "<br/>");
out.write(b.getValue().getPrice() + "<br/>");
out.write(b.getValue().getAuthor() + "<br/>");
}
}
// 回写cookie,保存最后浏览的商品id
String history = buildIds(id, request);
Cookie cookie = new Cookie("history", history);
cookie.setMaxAge(1 * 30 * 24 * 60 * 60);
cookie.setPath("/cookieTest");
response.addCookie(cookie);
}
private String buildIds(String id, HttpServletRequest request) {
String history = null;
Cookie[] cookies = request.getCookies();
for (int i = 0; cookies != null && i < cookies.length; i++) {
if (cookies[i].getName().equals("history")) {
history = cookies[i].getValue();
}
}
if (history == null) {
System.out.println(id);
return id;
}
LinkedList<String> ids = new LinkedList<String>(Arrays.asList(history
.split("\\-")));
if (ids.contains(id)) {
ids.remove(id);
} else {
if (ids.size() >= 3) { // 最多显示3条浏览历史
ids.removeLast();
}
}
ids.addFirst(id);
StringBuffer sb = new StringBuffer();
for (int j = 0; j < ids.size(); j++) {
if (j != ids.size() - 1) {
sb.append(ids.get(j)).append("-");
} else {
sb.append(ids.get(j));
}
}
System.out.println(sb);
return sb.toString();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
public class Book {
private String id;
private String name;
private double price;
private String author;
public Book(String id, String name, double price, String author) {
super();
this.id = id;
this.name = name;
this.price = price;
this.author = author;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
import java.util.LinkedHashMap;
import java.util.Map;
class Db {
private static Map<String, Book> books = new LinkedHashMap<String, Book>();
static {
books.put("1", new Book("1", "红楼梦", 15, "曹雪芹"));
books.put("2", new Book("2", "大漠谣", 20, "桐华"));
books.put("3", new Book("3", "诛仙", 15, "萧鼎"));
books.put("4", new Book("4", "朝花夕拾", 25, "鲁迅"));
}
public static Map<String, Book> getBooks() {
return books;
}
}
3. Session技术
1. 什么是Session
Session是服务器端技术,利用这个技术,服务器在运行时可以为每个用户的浏览器创建一个其独享的HttpSession对象,由于session为用户浏览器独享,所以用户在访问服务器的资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其他web资源时,其他的web资源再从用户的各自session中取出数据为用户服务
2. Session的核心技术
HttpSession类:用于保存会话数据,常用方法如下:
- 创建或得到session对象
HttpSession getSession():直接创建一个Session对象
HttpSession getSession():接收布尔值,设置为true时,在没有找到匹配Session编号的对象时新建一个Session对象
如果设置为false,则当找不到匹配的Session时,返回null
- 设置session对象
void setMaxInactiveInterval(int interval):设置session的有效时间
默认30分钟自动回收session对象
String getId():得到session编号
void invalidate():销毁session对象
- 保存会话数据到session对象
void setAttribute(String name,object value):保存数据
Object getAttribute(String name):获取数据
void removeAttribute(String name):清除数据
- 如何避免浏览器的JSESSIONID的cookie随着浏览器关闭而丢失的问题
解决方法是手动发送一个硬盘保护的cookie给浏览器
Demo:
public class SessionServletDemo extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 1.创建Session对象
HttpSession session = request.getSession();
// 2.保存会话数据
session.setAttribute("name", "eric");
// 3.取出会话数据
String name = (String) session.getAttribute("name");
System.out.println(name);
// 4.1拿到session的id
System.out.println(session.getId());
// 4.2修改session的有效时间
session.setMaxInactiveInterval(20);
// 4.3销毁session
if (session != null) {
session.invalidate();
}
// 5.手动发送一个硬盘保存的cookie给浏览器
Cookie c = new Cookie("JSESSION", session.getId());
c.setMaxAge(60 * 60);
response.addCookie(c);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
3. Session原理
代码解读:HttpSession session=request.getSession();
伪码分析执行过程
1. 第一次访问创建Session对象,给Session对象分配一个唯一的ID,叫JSESSIONID
new HttpSession();
- 把JSESSIONID作为Cookie的值发送给浏览器保存
Cookie cookie = new Cookie("JSESSIONID",sessionID);
response.addCookie(cookie);
- 第二次访问时,浏览器带着JSESSIONID的cookie访问服务器
- 服务器得到JSESSIONID,在服务器的内存中搜索是否存放对应编号的session对象
- 如果找到对应编号的session对象,直接返回此对象
- 如果找不到对应编号的session对象,创建新的session对象,继续走1的流程
结论:通过JSESSION的cookie值在服务器中找session对象
4. Session应用:用户登录效果
需求:实现用户登录效果,如果登录成功,显示欢迎回来,xxx。如果失败显示登录失败
默认登录页面:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>登录页面</title>
</head>
<body>
<form action="/cookieTest/servlet/loginServlet" method="post">
用户名:<input type="text" name="userName" /> <br />
密码:<input type="text" name="userPwd" /> <br />
<input type="submit" value="登录" />
</form>
</body>
</html>
登录失败页面:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>信息提示页面</title>
</head>
<body>
<font color='red' size='3'>亲,你的用户名或密码输入有误!请重新输入!</font>
<br />
<a href="/cookieTest/index.html">返回登录界面</a>
</body>
</html>
表单提交后的主处理逻辑:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class IndexServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String html = "";
HttpSession session = request.getSession(false);
if (session == null) {
response.sendRedirect(request.getContextPath() + "/index.html");
return;
}
String userName = (String) session.getAttribute("userName");
if (userName == null) {
response.sendRedirect(request.getContextPath() + "/index.html");
return;
}
html = "<html><body>欢迎回来," + userName + ",<a href='"
+ request.getContextPath()
+ "/servlet/logoutServlet'>安全退出</a></body></html>";
out.write(html);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
登录处理逻辑:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String userName = request.getParameter("userName");
String userPwd = request.getParameter("userPwd");
if ("eric".equals(userName) && "123456".equals(userPwd)) {
HttpSession session = request.getSession();
session.setAttribute("userName", userName);
response.sendRedirect(request.getContextPath() + "/servlet/indexServlet");
} else {
response.sendRedirect(request.getContextPath() + "/fail.html");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
退出处理逻辑:
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LogoutServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession(false);
if (session != null) {
session.removeAttribute("userName");
}
response.sendRedirect(request.getContextPath() + "/index.html");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
5. Session应用:购物车
public class Book {
private String id;
private String name;
private double price;
private String author;
public Book(String id, String name, double price, String author) {
super();
this.id = id;
this.name = name;
this.price = price;
this.author = author;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
import java.util.LinkedHashMap;
import java.util.Map;
class Db {
private static Map<String, Book> books = new LinkedHashMap<String, Book>();
static {
books.put("1", new Book("1", "红楼梦", 15, "曹雪芹"));
books.put("2", new Book("2", "大漠谣", 20, "桐华"));
books.put("3", new Book("3", "诛仙", 15, "萧鼎"));
books.put("4", new Book("4", "朝花夕拾", 25, "鲁迅"));
}
public static Map<String, Book> getBooks() {
return books;
}
public static Book findBookById(String id){
return books.get(id);
}
}
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ListServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.print("本网站有以下书籍:<br/>");
Map<String, Book> books = Db.getBooks();
for (Map.Entry<String, Book> book : books.entrySet()) {
String url = request.getContextPath() + "/servlet/addCart?id="
+ book.getKey();
out.print("<a href='" + response.encodeURL(url) + "'>"
+ book.getValue().getName() + "</a><br/>");
}
String url2 = request.getContextPath() + "/servlet/showCart";
out.print("<a href='" + response.encodeURL(url2) + "'>查看购物车</a>");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class AddCart extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String id = request.getParameter("id");
Book book = Db.findBookById(id);
HttpSession session = request.getSession();
List<Book> list = (List<Book>) session.getAttribute("cart");
if (list == null) {
list = new ArrayList<Book>();
}
list.add(book);
session.setAttribute("cart", list);
out.print("购买成功!");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class ShowCart extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.print("购物车有以下书籍:<br/>");
HttpSession session = request.getSession();
List<Book> books = (List<Book>) session.getAttribute("cart");
if (books == null) {
out.print("你还什么都没买呢");
response.setHeader("refresh", "2;url=" + request.getContextPath()
+ "/servlet/listServlet");
return;
}
for (Book book : books) {
out.write(book.getName() + "<br/>");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
本文详细介绍了会话管理技术的基本概念及其在Web开发中的应用,包括客户端Cookie技术和服务器端Session技术的工作原理、核心技术及实际应用场景。

被折叠的 条评论
为什么被折叠?



