会话技术

什么是会话

从浏览器访问服务器开始,到访问服务器结束,浏览器关闭为止的这段时间内容产生的多次请求和响应,合起来叫做浏览器和服务器之间的一次会话

会话管理作用

共享数据用的,并且是在不同请求间实现数据共享。

会话技术是为了解决客户端浏览器和服务端的通信问题。用户在网页上的操作会产生很多重要的并且需要被保存的数据。比如购物车信息,可能我们此时不会清空购物车,那么购物车的信息需要被完整的保存下来。再比如登陆网站只需要登陆一次,再登陆网站的其他网页时就不需要重复登陆了,这是因为用户信息被保存了。

数据能否用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的更多相关文章

  1. JavaWeb(二)cookie与session的应用

    前言 前面讲了一堆虚的东西,所以这篇我们来介绍一下cookie和session的应用. 一.使用cookie记住用户名 1.1.思路介绍 1.2.实现代码 1)LoginServlet package ...

  2. JavaWeb:Cookie处理和Session跟踪

    JavaWeb:Cookie处理和Session跟踪 Cookie处理 什么是Cookie Cookie 是存储在客户端计算机上的文本文件,保留了各种跟踪信息.因为HTTP协议是无状态的,即服务器不知 ...

  3. JavaWeb——Cookie,Session学习汇总

    什么是Cookie Cookie的作用 安全性能 Cookie的语法 Cookie注意细节 Cookie实例练习 什么是会话Session Session语法 Session与浏览器窗口的关系 ses ...

  4. JavaWeb学习之转发和重定向、会话技术:cookie、session、验证码实例、URLConnection使用(下载网页)(4)

    1.转发和重定向 HttpServletResponse response 转发: RequestDispatcher dispatcher = request.getRequestDispatche ...

  5. JavaWeb之Cookie和Session的区别

    Cookie和Session的区别 一.cookie机制和session机制的区别 ********************************************************** ...

  6. JavaWeb(二)会话管理之细说cookie与session

    前言 前面花了几篇博客介绍了Servlet,讲的非常的详细.这一篇给大家介绍一下cookie和session. 一.会话概述 1.1.什么是会话? 会话可简单理解为:用户开一个浏览器,点击多个超链接, ...

  7. JavaWeb系列之八(Cookie&amp;Session)

     1.jsp的入门     jsp就是一个servlet,终于会被编译成servlet,jsp:java server pages,java服务器端页面,包括html+java+jsp的指令    ...

  8. java基础学习:JavaWeb之Cookie和Session

    一.会话概述 1.1.什么是会话? 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话其中不管浏览器发送多少请求,都视为一次会话,直到 ...

  9. 基于javaWeb阶段下的Cookie和Session总结

    1. 会话技术   就是用户在使用浏览器浏览界面的时候,去访问多个页面后一次性关闭浏览器,这个过程叫会话,学习会话技术就是在客户端与服务器进行交互的时候为了能更好的保存数据.在java中会话技术只有C ...

  10. javaWeb核心技术第八篇之Cookie和Session

    会话技术: 会话是什么? 浏览器和服务器交互,浏览器打开网页访问服务器,会话开始,正常交互. 浏览器关闭,会话结束. 会话能干什么? 会话可以共享数据. Cookie和session将数据保存在不同的 ...

随机推荐

  1. JUC 并发编程--10, 阻塞队列之--LinkedBlockingDeque 工作窃取, 代码演示

    直接上代码 class LinkedBlockingDequeDemo { // 循环是否结束的开关 private static volatile boolean flag1 = true; pri ...

  2. 5.7w字?GitHub标星120K的Java面试知识点总结,真就物超所值了

    如果你觉得在一些程序员平台获取到的资料太乱学习起来毫无头绪,但是单看<Java编程思想>相似的一类的Java圣经"枯燥无味",那我推荐你看一下这份GitHub获得过12 ...

  3. 狂神说JUC学习笔记(一)

    狂神说JUC的原版笔记: 链接:https://pan.baidu.com/s/12zrGI4JyZhmkQh0cqEO4BA 提取码:d65c 我的笔记在狂神的笔记上增加了一些知识点或者做了些许修改 ...

  4. Java静态方法和实例方法的区别以及this的用法

    Java静态方法和实例方法 相同之处:都能接收传过来的参数,都能返回参数. 不同之处:有static就是静态方法,静态方法在另外一个类里面,不用new这个静态方法所在的类,也能直接访问这个方法,比较方 ...

  5. kube-proxy IPVS 模式的工作原理

    原文链接:https://fuckcloudnative.io/posts/ipvs-how-kubernetes-services-direct-traffic-to-pods/ Kubernete ...

  6. centos7 安装 bbr加速

    脚本安装 1 查看内核版本 # [root@os]# uname -a Linux os 3.10.0-1127.13.1.el7.x86_64 x86_64 x86_64 x86_64 GNU/Li ...

  7. 【NX二次开发】布尔操作

    //布尔操作 //UF_MODL_operations 对两个体执行布尔操作 //UF_MODL_unite_bodies 相加布尔操作,不可保留目标体.工具体 //UF_MODL_unite_bod ...

  8. winform/WPF 多语言的实现

    WPF实现起来非常现代化,可以参考 https://www.cnblogs.com/yang-fei/p/4854460.html winform主要说一下实现过程和注意点,实现参考AutoUpdat ...

  9. 从谭浩强的《C语言程序设计》到《电容应用分析精粹》

    不记得具体从什么时候开始(反正很多年前的事了)的,不少人都陆续批评过谭浩强的<C语言程序设计>,各方面都有扒过.例如,与实践脱节,很多例子在不同编译器上运行是错误的,代码风格糟糕等等方面. ...

  10. Keepalive介绍及工作原理

    注:keepalive和Nginx和高可用没有关联. 1.什么是高可用,为什么要设计高可用? 1.两台业务系统启动着相同的服务,如果有一台故障,另一台自动接管,我们将国称之为高可用.2.系统可用率算法 ...