会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。
从浏览器发出请求到服务端响应数据给前端之后,一次会话(在浏览器和服务器之间)就被建立了
会话被建立后,如果浏览器或服务端都没有被关闭,则会话就会持续建立着
浏览器和服务器就可以继续使用该会话进行请求发送和响应,上述的整个过程就被称之为会话。
会话跟踪:一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据。
服务器会收到多个请求,这多个请求可能来自多个浏览器,如上图中的6个请求来自3个浏览器
服务器需要用来识别请求是否来自同一个浏览器
服务器用来识别浏览器的过程,这个过程就是会话跟踪
服务器识别浏览器后就可以在同一个会话中多次请求之间来共享数据
问:为什么一个会话中的多次请求要共享数据?有了这个数据共享功能后能实现哪些功能?
答:
问:为什么现在浏览器和服务器不支持数据共享呢
答:
会话跟踪技术的实现方式有:Cookie(客户端会话跟踪技术)、Session(服务端会话跟踪技术)
两者之间的区别:Cookie是存储在浏览器端而Session是存储在服务器端
Cookie:客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问。
name=zs
的数据存入Cookie对于Cookie的使用,我们更关注的应该是后台代码如何操作Cookie,对于Cookie的操作主要分两大类,本别是发送Cookie和获取Cookie,对于上面这两块内容,分别该如何实现呢?
1)发送Cookie
创建Cookie对象,并设置数据
Cookie cookie = new Cookie("key","value");
发送Cookie到客户端:使用response对象
response.addCookie(cookie);
《Cookie发送案例》 创建Maven项目cookie-demo,并在pom.xml添加依赖
<!--servlet--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!--jsp--> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2</version> <scope>provided</scope> </dependency> <!--jstl--> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency>
编写Servlet类,名称为AServlet,并在Servlet中创建Cookie对象,存入数据,发送给前端
package com.bby; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; @WebServlet("/aServlet") public class AServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //发送Cookie //1.创建Cookie对象 Cookie cookie = new Cookie("username", "bby"); //2.发送Cookie,response response.addCookie(cookie); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request,response); } }
配置Tomcat
启动项目测试,浏览器查看Cookie的值
访问http://localhost:8080/aServlet
方式一:浏览器设置中查看,此处使用 Edge浏览器查看(新版火狐和谷歌浏览器都不能查看具体信息)
方式二:浏览器(此处以谷歌浏览器为例)中按下 F12
2)获取Cookie
获取客户端携带的所有Cookie,使用request对象
Cookie[] cookies = request.getCookies();
遍历数组,获取每一个Cookie对象
使用Cookie对象方法获取数据
for(Cookie cookie : cookies) { cookie.getName(); cookie.getValue(); }
《Cookie获取案例》 编写一个新Servlet类,名称为BServlet
package com.bby; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/bServlet") public class BServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取Cookie //1. 获取Cookie数组 Cookie[] cookies = req.getCookies(); //2. 遍历数组 for (Cookie cookie : cookies) { //3. 获取数据 String name = cookie.getName(); if (name.equals("username")) { String value = cookie.getValue(); System.out.println(name + ":" + value); } } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } }
启动项目测试
对于Cookie的实现原理是基于HTTP协议的,其中设计到HTTP协议中的两个请求头信息:
Set-Cookie:username=zs
Set-Cookie
对应值username=zs
,并将数据存储在浏览器的内存中Cookie: username=zs
发送给服务端BServlet《验证上述结论》
访问http://localhost:8080/bServlet
从响应头获取到Set-Cookie
对应值username=bby
访问http://localhost:8080/bServlet
向请求头中添加Cookie: username=bby
在使用Cookie时我们要注意两点:第一个是Cookie的存活时间,第二个是Cookie如何存储中文
思考:当我们关闭浏览器后再重新打开,AServlet响应存有的username=bby
的Cookie对象给浏览器还存在吗?
结论:不存在,当我们关闭浏览器后再通过BServlet访问这个Cookie对象时就获取不到了
原因:默认情况下,Cookie存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁
《实际案例分析》 分析
当我们登录的时候在账号和密码下方有一个“记住我”的按钮,这个功能就相当于第一次输入用户名和密码并勾选后进行登录,下次再登陆的时候,用户名和密码就会被自动填充,不需要再重新输入登录。但是我们要是使用默认的Cookie,浏览器一关,Cookie就会从浏览器内存中被删除,这个功能就无法实现了
如何将Cookie持久化存储?
Cookie其实已经为我们提供好了对应的API来完成这件事,这个API就是setMaxAge
设置Cookie存活时间
setMaxAge(int seconds)
参数值为:
1.正数:将Cookie写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除
2.负数:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则Cookie被销毁
3.零:删除对应Cookie
《案例:设置Cookie存活时间》 编写Servlet
package com.bby; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.annotation.*; import java.io.IOException; @WebServlet("/aServlet") public class AServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //发送Cookie //1.创建Cookie对象 Cookie cookie = new Cookie("username", "bby"); cookie.setMaxAge(7*24*60*60); //7天,这样写便于阅读 //cookie.setMaxAge(604800); //不易阅读(可以使用注解弥补),程序少进行一次计算 //2.发送Cookie,response response.addCookie(cookie); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request,response); } }
运行项目测试
先访问一次http://localhost:8080/aServlet,然后关闭浏览器并重启,访问http://localhost:8080/bServlet,能在控制台打印出username:bby
,说明Cookie没有随着浏览器关闭而被销毁
可以看到Cookie的创建时间与到期时间相差一周,如下图
Cookie直接存储中文会发生什么?
修改代码
运行测试
结论:Cookie不能直接存储中文
解决方式:先对中文进行URL编码,采用URLEncoder.encode(),将编码后的值存入Cookie中,再将获取到的值进行解码
编码
String value = "啵啵鱼"; //对中文进行URL编码 value = URLEncoder.encode(value, "UTF-8"); //将编码后的值存入Cookie中 Cookie cookie = new Cookie("username",value);
解码
//将获取的Cookie值进行解码 //URL解码 value = URLDecoder.decode(value,"UTF-8");
这样,我们就可以将中文存入Cookie中进行使用。
下节我们讲解Session