【Javaweb】Cookie和Session
会话技术
什么是会话
从浏览器访问服务器开始,到访问服务器结束,浏览器关闭为止的这段时间内容产生的多次请求和响应,合起来叫做浏览器和服务器之间的一次会话
会话管理作用
共享数据用的,并且是在不同请求间实现数据共享。
会话技术是为了解决客户端浏览器和服务端的通信问题。用户在网页上的操作会产生很多重要的并且需要被保存的数据。比如购物车信息,可能我们此时不会清空购物车,那么购物车的信息需要被完整的保存下来。再比如登陆网站只需要登陆一次,再登陆网站的其他网页时就不需要重复登陆了,这是因为用户信息被保存了。
数据能否用HttpServletRequest或者ServletContext保存呢?
不能用 HttpServletRequest 的原因:我们的一次会话中,存在多次请求和响应,而浏览器客户端的每一次请求都会产生一个 HttpServletRequest 对象,它只会保存此次请求的信息,例如放入购物车与购买付款是不同的请求,很显然数据没有得到很好的保存处理
不能用 ServletContext 的原因:ServletContext对象是被整个web应用所共享的,将数据都存到这里,无疑会无法区分具体信息的归属
会话管理分类
客户端会话管理技术
它是把要共享的数据保存到了客户端(也就是浏览器端)。每次请求时,把会话信息带到服务器,从而实现多次请求的数据共享。
服务端会话管理技术
它本质仍是采用客户端会话管理技术,只不过保存到客户端的是一个特殊的标识,并且把要共享的数据保存到了服务端的内存对象中。每次请求时,把这个标识带到服务器端,然后使用这个标识,找到对应的内存空间,从而实现数据共享。
Cookie
Cookie 概述
Cookies是服务器在本地机器上存储的小段文本并随每一个请求发送至同一服务器,是在客户端保持状态的方案,是客户端浏览器的缓存文件,里面记录了客户浏览器访问网站的一些内容。同时,也是HTTP协议请求和响应消息头的一部分
常用API
| 属性名称 | 属性作用 | 是否重要 |
|---|---|---|
| name | cookie的名称 | 必要属性 |
| value | cookie的值(不能是中文) | 必要属性 |
| path | cookie的路径 | 重要 |
| domain | cookie的域名 | 重要 |
| maxAge | cookie的生存时间。 | 重要 |
| version | cookie的版本号。 | 不重要 |
| comment | cookie的说明。 | 不重要 |
注意细节
Cookie有大小,个数限制。每个网站最多只能存20个cookie,且大小不能超过4kb。同时,所有网站的cookie总数不超过300个。
当删除Cookie时,设置maxAge值为0。当不设置maxAge时,使用的是浏览器的内存,当关闭浏览器之后,cookie将丢失。设置了此值,就会保存成缓存文件(值必须是大于0的,以秒为单位)。
常用方法
| 返回值 | 方法 | 作用 |
|---|---|---|
| String | getName() | 返回cookie的name |
| String | getValue() | 返回当前cookie的value |
| void | setMaxAge() | 设置Cookie最大存活时间 |
构造方法:
Cookie(String name, String value)
- 通过指定的名称和值构造一个Cookie
- Cookie的名称必须遵循RFC 2109规范。这就意味着,它只能包含ASCII字母数字字符,
- 不能包含逗号、分号或空格或以$字符开头。
- 创建后无法更改cookie的名称。
- 该值可以是服务器选择发送的任何内容。
- 它的价值可能只有服务器才感兴趣。
- 创建之后,可以使用setValue方法更改cookie的值。
向浏览器添加Cookie:
public void addCookie(Cookie cookie);
- 添加Cookie到响应中。此方法可以多次调用,用以添加多个Cookie。
从服务器端获取Cookie:
public Cookie[] getCookies();
- 这是HttpServletRequest中的方法。
- 它返回一个Cookie的数组,包含客户端随此请求发送的所有Cookie对象。
- 如果没有符合规则的cookie,则此方法返回null。
Cookie的路径限制
取自第一次访问的资源路径前缀
只要以这个前缀为开头(包括子级路径),可以获取到
反之获取不到
举例:
@WebServlet("/servlet/servletDemo02")
public class ServletDemo02 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建Cookie并添加
Cookie cookie = new Cookie("username","zhangsan");
cookie.setMaxAge(3600);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
@WebServlet("/servlet/servletDemo03")
public class ServletDemo03 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取Cookie
Cookie[] arr = req.getCookies();
for(Cookie c : arr) {
if("username".equals(c.getName())) {
String value = c.getValue();
resp.getWriter().write(value);
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
@WebServlet("/servlet/aaa/servletDemo04")
public class ServletDemo04 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取Cookie
Cookie[] arr = req.getCookies();
for(Cookie c : arr) {
if("username".equals(c.getName())) {
String value = c.getValue();
resp.getWriter().write(value);
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
@WebServlet("/bbb/servletDemo05")
public class ServletDemo05 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取Cookie
Cookie[] arr = req.getCookies();
for(Cookie c : arr) {
if("username".equals(c.getName())) {
String value = c.getValue();
resp.getWriter().write(value);
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
第一次访问的路径是/servlet/servletDemo02
前缀是\servlet
/servlet/servletDemo03和/servlet/aaa/servletDemo04可以获取到Cookie的值
而/bbb/servletDemo05不能获得Cookie的值,因为前缀不同
Cookie 应用:显示最后一次登陆时间
/*
Cookie的使用
*/
@WebServlet("/servletDemo01")
public class ServletDemo01 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.通过响应对象写出提示信息
resp.setContentType("text/html;charset=UTF-8");
PrintWriter pw = resp.getWriter();
pw.write("欢迎访问本网站,您的最后访问时间为:<br>");
//2.创建Cookie对象,用于记录最后访问时间
Cookie cookie = new Cookie("time",System.currentTimeMillis()+"");
//3.设置最大存活时间
//cookie.setMaxAge(3600);
cookie.setMaxAge(0); // 立即清除
//4.将cookie对象添加到客户端
resp.addCookie(cookie);
//5.获取cookie
Cookie[] arr = req.getCookies();
for(Cookie c : arr) {
if("time".equals(c.getName())) {
//6.获取cookie对象中的value,进行写出
String value = c.getValue();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
pw.write(sdf.format(new Date(Long.parseLong(value))));
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
Session
Session概述
Cookie 在客户端浏览器保存Session标识JSESSIONID,而每一个JSESSIONID对应的数据存储在服务器,客户端每次发出请求时会一块把JSESSIONID发送给服务器,服务器通过这个表实标识寻找对应的数据并把其响应给客户端。
当用户在应用程序的 Web页间跳转时,存储在 Session 对象中的变量不会丢失而是在整个用户会话中一直存在下去。
HttpSession 对象
它是Servlet规范中提供的一个接口。该接口的实现由Servlet规范的实现提供商提供。我们使用的是Tomcat服务器,它对Servlet规范进行了实现,所以HttpSession接口的实现由Tomcat提供。该对象用于提供一种通过多个页面请求或访问网站来标识用户并存储有关该用户的信息的方法。简单说它就是一个服务端会话对象,用于存储用户的会话数据。
同时,它也是Servlet规范中四大域对象之一的会话域对象。并且它也是用于实现数据共享的。
| 域对象 | 作用范围 | 使用场景 |
|---|---|---|
| ServletContext | 整个应用范围 | 当前项目中需要数据共享时,可以使用此域对象。 |
| ServletRequest | 当前请求范围 | 在请求或者当前请求转发时需要数据共享可以使用此域对象。 |
| HttpSession | 会话返回 | 在当前会话范围中实现数据共享。它可以在多次请求中实现数据共享。 |
HttpSession 常用方法
获取HttpSession对象的方法:
public HttpSession getSession();
public HttpSession getSeesion(boolean create);


Session 使用案例
/*
Session的基本使用
*/
@WebServlet("/servletDemo01")
public class ServletDemo01 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取请求的用户名
String username = req.getParameter("username");
//2.获取HttpSession的对象
HttpSession session = req.getSession();
System.out.println(session);
System.out.println(session.getId());
//3.将用户名信息添加到共享数据中
session.setAttribute("username",username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
/*
Session的基本使用
*/
@WebServlet("/servletDemo02")
public class ServletDemo02 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取HttpSession对象
HttpSession session = req.getSession();
System.out.println(session);
System.out.println(session.getId());
//2.获取共享数据
Object username = session.getAttribute("username");
//3.将数据响应给浏览器
resp.getWriter().write(username+"");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
Cookie禁用时的处理方案
方案一(推荐)
直接提示Cookie被禁用了
/*
Cookie的禁用
*/
@WebServlet("/servletDemo03")
public class ServletDemo03 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取HttpSession对象
HttpSession session = req.getSession(false); //若JSESSIONID不存在,则不创建新HttpSession对象
System.out.println(session);
if(session == null) {
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("为了不影响正常的使用,请不要禁用浏览器的Cookie~");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
方案二(重写URL)
客户端浏览器如果关闭Cookie权限,就无法把JSESSIONID传给服务器,如果想实现页面共享,就需要把JSESSIONID通过URL传递给服务器。也就是把JSESSIONID直接附加在URL路径的后面。
String encodeURL(String url)
Encodes the specified URL by including the session ID, or, if encoding is not needed, returns the URL unchanged. The implementation of this method includes the logic to determine whether the session ID needs to be encoded in the URL. For example, if the browser supports cookies, or session tracking is turned off, URL encoding is unnecessary.
@WebServlet("/servletDemo01")
public class ServletDemo01 extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取请求的用户名
String username = req.getParameter("username");
//2.获取HttpSession的对象
HttpSession session = req.getSession();
System.out.println(session);
System.out.println(session.getId());
//3.将用户名信息添加到共享数据中
session.setAttribute("username",username);
//实现url重写 相当于在地址栏后面拼接了一个jsessionid
resp.getWriter().write("<a href='"+resp.encodeURL("http://localhost:8080/session/servletDemo03")+"'>go servletDemo03</a>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
点击连接以后,发现URL显示http://localhost:8080/ServletDemo13;jsessionid=AEAFBD306F72BF3379A660596277E4C9
encodeURL方法使地址自动附加了JSESSIONID
HttpSession的钝化和活化
什么是持久态
把长时间不用,但还不到过期时间的HttpSession进行序列化,写到磁盘上。
我们把HttpSession持久态也叫做钝化。(与钝化相反的,我们叫活化。)
什么时候使用持久化
第一种情况:当访问量很大时,服务器会根据getLastAccessTime来进行排序,对长时间不用,但是还没到过期时间的HttpSession进行持久化。
第二种情况:当服务器进行重启的时候,为了保持客户HttpSession中的数据,也要对HttpSession进行持久化
注意
HttpSession的持久化由服务器来负责管理,我们不用关心。
只有实现了序列化接口的类才能被序列化,否则不行。
【Javaweb】Cookie和Session的更多相关文章
- JavaWeb(二)cookie与session的应用
前言 前面讲了一堆虚的东西,所以这篇我们来介绍一下cookie和session的应用. 一.使用cookie记住用户名 1.1.思路介绍 1.2.实现代码 1)LoginServlet package ...
- JavaWeb:Cookie处理和Session跟踪
JavaWeb:Cookie处理和Session跟踪 Cookie处理 什么是Cookie Cookie 是存储在客户端计算机上的文本文件,保留了各种跟踪信息.因为HTTP协议是无状态的,即服务器不知 ...
- JavaWeb——Cookie,Session学习汇总
什么是Cookie Cookie的作用 安全性能 Cookie的语法 Cookie注意细节 Cookie实例练习 什么是会话Session Session语法 Session与浏览器窗口的关系 ses ...
- JavaWeb学习之转发和重定向、会话技术:cookie、session、验证码实例、URLConnection使用(下载网页)(4)
1.转发和重定向 HttpServletResponse response 转发: RequestDispatcher dispatcher = request.getRequestDispatche ...
- JavaWeb之Cookie和Session的区别
Cookie和Session的区别 一.cookie机制和session机制的区别 ********************************************************** ...
- JavaWeb(二)会话管理之细说cookie与session
前言 前面花了几篇博客介绍了Servlet,讲的非常的详细.这一篇给大家介绍一下cookie和session. 一.会话概述 1.1.什么是会话? 会话可简单理解为:用户开一个浏览器,点击多个超链接, ...
- JavaWeb系列之八(Cookie&Session)
1.jsp的入门 jsp就是一个servlet,终于会被编译成servlet,jsp:java server pages,java服务器端页面,包括html+java+jsp的指令 ...
- java基础学习:JavaWeb之Cookie和Session
一.会话概述 1.1.什么是会话? 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话其中不管浏览器发送多少请求,都视为一次会话,直到 ...
- 基于javaWeb阶段下的Cookie和Session总结
1. 会话技术 就是用户在使用浏览器浏览界面的时候,去访问多个页面后一次性关闭浏览器,这个过程叫会话,学习会话技术就是在客户端与服务器进行交互的时候为了能更好的保存数据.在java中会话技术只有C ...
- javaWeb核心技术第八篇之Cookie和Session
会话技术: 会话是什么? 浏览器和服务器交互,浏览器打开网页访问服务器,会话开始,正常交互. 浏览器关闭,会话结束. 会话能干什么? 会话可以共享数据. Cookie和session将数据保存在不同的 ...
随机推荐
- 像Swing这种已经不太用的技术,大学还在教,到底要不要学?
一直以来,写日常问题.前沿技术和架构思考类的文章比较多,今天为什么突然来说说Swing这个陈年老技术呢? 因为在CSDN上看到了这样的一篇文章: 可以看到作者对于学Swing还是挺愤怒的,不过确实Sw ...
- Kafka源码分析(三) - Server端 - 消息存储
系列文章目录 https://zhuanlan.zhihu.com/p/367683572 目录 系列文章目录 一. 业务模型 1.1 概念梳理 1.2 文件分析 1.2.1 数据目录 1.2.2 . ...
- 基于webpack5封装的cli工具packx
安装 用 npm / yarn 安装: $ npm install -D packx $ yarn add -D packx 特性 基于 webpack5 支持 less,sass 支持 spa/mp ...
- mturoute 最大传输单元路由检测Host
mturoute检测mtu字符 下载地址:https://www.elifulkerson.com/projects/mturoute.php mturoute.exe ...
- 【源码分析】- 在SpringBoot中你会使用REST风格处理请求吗?
目录 前言 1.什么是 REST 风格 1.1 资源(Resources) 1.2 表现层(Representation) 1.3 状态转化(State Transfer) 1.4 综述 ...
- Pun(PhotonUnityNetwork)
介绍 Photon Unity Networking(首字母缩写 PUN)是一个 Unity 多人游戏插件包.它提供了身份验证选项.匹配,以及快速.可靠的通过我们的 Photon 后端实现的游戏内通信 ...
- 试着给VuePress添加全局禁止爬取支持,基于vuepress-plugin-robots
背景 有时候,我们有些内部网站希望不被外部抓取,那么我们可以借助vuepress-plugin-robots来生成robots.txt文件,来告诉爬虫不要抓取页面. 安装 npm install vu ...
- 从零开始学前端,React框架背后的核心机制和原理JSX
什么是React React是起源于Facebook的一个前端框架,用于构建用户界面的JavaScript库,Facebook用来探索一种更加高效优雅的Javascript MVC框架来架设Insta ...
- 双向链表(DoubleLinkList)
双向链表 有关链表的知识可以点击我上篇文章这里就不再赘述LinkedList 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的任意一个 ...
- 10、基本数据类型(set)
10.1.集合: 1.集合元素用大括号括起来,用逗号分割每个元素 2.集合的特点: (1)集合元素的数据类型只能是不可变数据类型,"列表"."字典"." ...