1.6(学习笔记)Session
一、 Session简介
Session是用于解决HTTP无状态问题,HTTP协议本身是没有状态的,
就类似一个没有记性的商人,每次只交易当前的货物,交易完后就忘记了
以前的交易历史。我们和商人交易时当然希望商人记住我们的一些信息,
(例如购买的货物等),这样商人就可以根据我们的信息,提供一些定制
的服务。
而Session、Cookie就是解决商人的记性问题,使商人能够记住我们的信息。
Cookie可参阅:
现在商人想了一个办法,他每次交易后给我们一张小卡片,卡片上只有一个编号。
然后商人这里有一个记账本,每次交易时我们把小卡片给商人,商人根据小卡片上面的
编号修改自己的记账本。这个记账本就是Session,这个编号是Session ID,这个小卡片
是Cookie。
Session是存储在服务器的,Cookie是存储在客户端的。
Session的创建
Session在用户端访问时便不会被默认创建,而是通过request.getSession();创建第一个Session.
//如果存在Session则返回关联的Session,如果不存在则创建Session。
HttpSession request.getSession();
Session的销毁
Session销毁主要有两种情况,一是手动销毁通过调用session.invalidate()方法销毁。
二是Session默认30分钟没有使用,则服务器自动销毁。
默认销毁时间可以通过web.xml中设置,单位是分钟。
<session-config>
<!--设置Session默认有效期,单位分钟-->
<session-timeout>15</session-timeout>
</session-config>
Session会话过程
首先但不存在Session时,调用request.getSession()会创建一个Session。
同时这个Session的ID会以Cookie写入到客户端。
下一次客户端访问服务器时,reques会发送Cookie,服务器就会读取Cookie中
对应的SessionID,然后服务器根据读取的SessionID寻找存储的Session。
Session的URL重定向
由上述得知,Session的ID使用Cookie存储在客户端,但是这种方法并不可靠。
用户可能禁用Cookie,Cookie被禁用后我们就无法通过Cookie获取SessionID,
这时就需要采用URL重定向将SessionID以参数的形式作为URL的一部分传递给服务器,
以保障Session在Cookie禁用的情况下能正常使用。
二、Session实例
用户购买书籍,通过Session记录已购买书籍。
程序流程:
BuyIndexServlet:
根据图书编号动态生成将购买带书籍ID作为参数传递的的购买链接。
点击购买链接后,跳转到BuyServlet。
BuyServlet:
session = getSession();
//获取Session中用户购书清单
list = session.getAttribute("lisi");
if(list == null){
new list;
}
list.add("用户选中图书")
session.setAttribute(list);
请求跳转到showBuyBookServlet。
showBuyBookServlet:
//获取Session中书籍购买清单
llist = request.getSession().getAttribute("list");
遍历输出list内容,即已购买书籍。
Cookie未禁用版本:
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; 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{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
//打印HTML头部代码
HttpPageUtil.printHtmlPage(out,true);
//生产将书籍ID作为参数的购买链接
//链接:http://localhost:8080/TestServlet/TestServlet/BuyServlet?id=3
for(Entry<String, Book> s : Lib.getAll().entrySet()) {
Book book = s.getValue();
out.println("<a href = "+ req.getContextPath() + "/TestServlet/BuyServlet?id="+ book.getId() +">"
+ book.getName() +"</a>");
}
//打印HTML尾部代码
HttpPageUtil.printHtmlPage(out,false);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
} //全部书籍
class Lib{
private static Map<String,Book> map = new HashMap<>();
static {
map.put("1", new Book("1","深入理解操作系统"));
map.put("2", new Book("2","计算机网络"));
map.put("3", new Book("3","数据结构与算法"));
map.put("4", new Book("4","计算机组成原理"));
map.put("5", new Book("5","编译原理"));
} public static Map<String,Book> getAll(){
return map;
}
} class Book{
private String id;
private String name;
public String getId() {
return id;
} public Book() {}; public Book(String id, String name) {
setId(id);
setName(name);
} public void setId(String id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
BuyServlet:
import java.io.IOException;
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 BuyServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
String buyBookId = req.getParameter("id");
//获取Session中的书籍购买清单
List<Book> list = (List<Book>)session.getAttribute("list");
if(list == null) {
list = new ArrayList<>();
}
//将选中书籍添加到清单中
list.add(Lib.getAll().get(buyBookId));
session.setAttribute("list", list);
//请求转发到显示界面。
req.getRequestDispatcher("/TestServlet/showBuyBook").forward(req, resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
showBuyBookServlet:
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 showBuyBook extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
HttpSession session = req.getSession();
//获取Session中的书籍购买清单
List<Book> list = (List)session.getAttribute("list");
if(list == null){
out.println("<h1>你没有购买任何商品</h1>");
return;
}
HttpPageUtil.printHtmlPage(out, true);
//输出已购买书籍
for(Book book : list) {
out.println("<h2>" + book.getName() + " </h2>");
}
HttpPageUtil.printHtmlPage(out, false);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
Cookie被禁用版:(通过URL重写,将SessionID作为URL的参数传递)。
但Cookie被禁用使用Session时,主要通过传递SessionID来实现Session的共享。
而Session则将被作为URL的一部分,这需要使用URL重写方法。
String javax.servlet.htttp.HttpServletResponse.encodeURL(java.lang.String url);
将SessionID添加到URL,生成新的URL。
(如果Cookie没有被禁用则此方法不生效,只有Cookie被禁用此方法才生效)
BuyIndexServlet
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set; 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{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
req.getSession();//创建Session
PrintWriter out = resp.getWriter();
//打印HTML头部代码
HttpPageUtil.printHtmlPage(out,true);
//生产将书籍ID作为参数的购买链接
//链接:http://localhost:8080/TestServlet/TestServlet/BuyServlet?id=3
for(Entry<String, Book> s : Lib.getAll().entrySet()) {
Book book = s.getValue();
String url = req.getContextPath() + "/TestServlet/BuyServlet?id="+ book.getId();
//重写URL,将SessionID添加到URL中
//重写前URL:http://localhost:8080/TestServlet/TestServlet/BuyServlet?id=1
//重写后URL:
//http://localhost:8080/TestServlet/TestServlet/BuyServlet;jsessionid=A6722323929D7B76FE66B6F39E188D87?id=1
//其中jsessionid代表sessionID
url = resp.encodeURL(url);
out.println("<a href = " + url +"> " + book.getName() +"</a>");
}
//打印HTML尾部代码
HttpPageUtil.printHtmlPage(out,false);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
} //全部书籍
class Lib{
private static Map<String,Book> map = new HashMap<>();
static {
map.put("1", new Book("1","深入理解操作系统"));
map.put("2", new Book("2","计算机网络"));
map.put("3", new Book("3","数据结构与算法"));
map.put("4", new Book("4","计算机组成原理"));
map.put("5", new Book("5","编译原理"));
} public static Map<String,Book> getAll(){
return map;
}
} class Book{
private String id;
private String name;
public String getId() {
return id;
} public Book() {}; public Book(String id, String name) {
setId(id);
setName(name);
} public void setId(String id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
BuyServlet:
import java.io.IOException;
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 BuyServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
String buyBookId = req.getParameter("id");
//获取Session中的书籍购买清单
List<Book> list = (List<Book>)session.getAttribute("list");
if(list == null) {
list = new ArrayList<>();
}
//将选中书籍添加到清单中
list.add(Lib.getAll().get(buyBookId));
session.setAttribute("list", list);
//重写URL,并重定向到重写后的URL。
//重写后的URL:
//http://localhost:8080/TestServlet/TestServlet/showBuyBook;jsessionid=A6722323929D7B76FE66B6F39E188D87
String url = resp.encodeRedirectURL(req.getContextPath() + "/TestServlet/showBuyBook");
resp.sendRedirect(url);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
showBuyBookSelvelt:与Coolie未禁用版相同。
可以看到地址栏右边的一个图标有一个小红叉,代表禁用Cookie。但Cookie禁用后,无法从Cookie读取到SessionID。
此时主要通过URL重写来传递SessionID,其他Servlet可以通过传递过来的SessionID获取Session。
而且我们会发现,重写的URL都加上了jsessionid=....;这就是SessionID,服务器主要通过
这个ID来寻找存储的Session。
参考资料:
https://www.cnblogs.com/xdp-gacl/p/3855702.html
https://www.cnblogs.com/lonelydreamer/p/6169469.html
https://blog.csdn.net/weixin_42139757/article/details/80467518
1.6(学习笔记)Session的更多相关文章
- 重温Servlet学习笔记--session对象
session的类型是属于HttpSession,HttpSession是由javaWeb提供的,用来会话跟踪的类.session是服务器端对象,保存在服务器端. HttpSession是servle ...
- PHP学习笔记-session
session 在windows中的默认保存在AppDate/Local/Temp
- 2015.03.13,外语,读书笔记-《Word Power Made Easy》 10 “如何讨论交谈习惯”学习笔记 SESSION 26
1.a Spartan virtue 古斯巴达人中一位有名的Laconia国王,其言语比Vermonter(美国佛蒙特州人)还简洁.一个传说,马其顿菲利普国王(亚历山大的老爸)要进攻他们的都城,发了一 ...
- 2015.03.12,外语,读书笔记-《Word Power Made Easy》 10 “如何讨论交谈习惯”学习笔记 SESSION 25
1.about keeping one's mouth shut taciturn,名词形式taciturnity,沉默寡言. 美国第30任总统库里奇,以沉默寡言著称.他来自新英格兰,那里视tacit ...
- Tensorflow学习笔记2:About Session, Graph, Operation and Tensor
简介 上一篇笔记:Tensorflow学习笔记1:Get Started 我们谈到Tensorflow是基于图(Graph)的计算系统.而图的节点则是由操作(Operation)来构成的,而图的各个节 ...
- [原创]java WEB学习笔记94:Hibernate学习之路---session 的管理,Session 对象的生命周期与本地线程绑定
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记79:Hibernate学习之路--- 四种对象的状态,session核心方法:save()方法,persist()方法,get() 和 load() 方法,update()方法,saveOrUpdate() 方法,merge() 方法,delete() 方法,evict(),hibernate 调用存储过程,hibernate 与 触发器协同工作
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记78:Hibernate学习之路---session概述,session缓存(hibernate 一级缓存),数据库的隔离级别,在 MySql 中设置隔离级别,在 Hibernate 中设置隔离级别
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记77:Hibernate学习之路---Hibernate 版本 helloword 与 解析,.环境搭建,hibernate.cfg.xml文件及参数说明,持久化类,对象-关系映射文件.hbm.xml,Hibernate API (Configuration 类,SessionFactory 接口,Session 接口,Transaction(事务))
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记48:其他的Servlet 监听器:域对象中属性的变更的事件监听器 (3 个),感知 Session 绑定的事件监听器(2个)
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
随机推荐
- Android 网络编程--上传文件及相应的参数到服务器
之前一直在做SiteCheck的项目,所用到的知识大部分都涉及到网络编程方面,所以现在有时间先把它的使用方法及一些注意事项记录下来.在这里我用两种例子让大家了解它的使用方法: (1)上传图片及相应参数 ...
- Ubuntu下修改NAT模式的IP地址
1,查看虚拟机的网段 在编辑->虚拟网络编辑器->NAT设置->网关 IP 可以查看到虚拟机的网关 如图 2,图形化设置: 图中 Netmask设置的是255.255.255.0 ...
- 【Foreign】异色弧 [树状数组]
异色弧 Time Limit: 20 Sec Memory Limit: 256 MB Description Input Output 仅一行一个整数表示答案. Sample Input 8 1 ...
- bzoj 1692: [Usaco2007 Dec]队列变换 ——二分+hash
Description FJ打算带他的N(1 <= N <= 30,000)头奶牛去参加一年一度的“全美农场主大奖赛”.在这场比赛中,每个参赛者都必须让他的奶牛排成一列,然后领她们从裁判席 ...
- bzoj 1060 贪心
设根到每个叶子节点的距离为dis,比较容易的看出来,我们需要把这颗树的所有叶子节点的值都变成其中最大的内个,我们设为max,那么对于一颗子树来说,设其中dis值最大的为x,我们需要将这个子树根节点和子 ...
- mongodb的集合操作
MongoDB 创建集合 1.手动创建: 语法格式: db.createCollection(name, options) 参数说明: name: 要创建的集合名称 options: 可选参数, 指定 ...
- kuangbin带你飞 并查集 题解
做这套题之前一直以为并查集是很简单的数据结构. 做了才发现自己理解太不深刻.只看重片面的合并集合.. 重要的时发现每个集合的点与这个根的关系,这个关系可以做太多事情了. 题解: POJ 2236 Wi ...
- python基础===取txt文件的若干行到另一个文件
#取txt文件 的若干行到另一个txt f1 = open(r'F:\movie.txt','rb') f2= open(r'F:\movie2.txt','ab') i=0 while True: ...
- Java坦克大战 (二) 之画一个能动的圆圈代表坦克
本文来自:小易博客专栏.转载请注明出处:http://blog.csdn.net/oldinaction 在此小易将坦克大战这个项目分为几个版本,以此对J2SE的知识进行回顾和总结,希望这样也能给刚学 ...
- 关于 svn: E155004 is already locked 出现原因和解决办法
1.出错提示: svn: E155004 is already locked,please clean up ......... 2.出错原因: SVN 本地更新时,由于一些操作中断更新,如磁盘空间 ...