JavaWeb基础专项复习4——会话对象Session and Cookie
系列文章目录
1、JavaWeb基础专项复习1——XML文件-CSDN博客
2、JavaWeb基础专项复习2——JSP文件-CSDN博客
3、JavaWeb基础专项复习2——Servlet相关知识-CSDN博客
文章目录
- 编辑系列文章目录
- 文章目录
- 1、Cookie概述
- 1.1 什么叫Cookie
- 1.2 Cookie规范
- 1.3 Cookie的作用
- 2、 Cookie示例
- 2.1 保存Cookie到客户端
- 2.2 服务器端读取Cookie
- 3、Cookie生命周期(熟练)
- 4、Cookie的浏览器管理(熟练)
- 4.1 Google Chrom
- 4.2 Firefox
- 4.2.2 查看Cookie
- 4.2.3 清理Cookie
- 5、Cookie的路径
- 5.1 Cookie的path属性
- 5.2 Cookie 路径的作用
- 5.3 Cookie路径的使用
- 6、Cookie保存中文(熟练)
- 6.1 Cookie中保存中文
- 7、 Cookie的禁用
- 8、HttpSession概述
- 8.1 会话跟踪之session
- ServletContext
- HttpSession
- HttpServletRequest
- 8.2 获取session对象
- 9、HttpSession原理(依赖Cookie)
- 10、HttpSession失效(精通)
- 11、请求转发和重定向
- 11.1 转发(Forward)
- 11.1.1 原理
- 11.1.3 实现方式
- 11.1.4 特点
- 11.1.5 适用场景
- 11.2 重定向(Redirect)
- 11.2.1 原理
- 11.2.2 实现方式
- 11.2.3 特点
- 11.2.4 适用场景
1、Cookie概述
1.1 什么叫Cookie
Cookie翻译成中文是小甜点,小饼干的意思。在HTTP中它表示服务器送给客户端浏览器的小甜点。其实Cookie就是一个键和一个值构成的,随着服务器端的响应发送给客户端浏览器。然后客户端浏览器会把Cookie保存起来,当下一次再访问服务器时把Cookie再发送给服务器。
1.2 Cookie规范
你大可以放心,Cookie不会占满你的硬盘。因为一个Cookie最多只有4KB,并且浏览器最多可以保存300个Cookie。当然,在浏览器大战的今天,一些浏览器为了打败对手,可能对Cookie规范“扩展”了一些,例如每个Cookie的大小为8KB,最多可保存500个Cookie等。但也不会出现把你硬盘占满的可能。
不同的浏览器之间不能共享Cookie
1.3 Cookie的作用
Cookie的作用可大了,但无论怎么夸大Cookie的作用都离不开“跟踪客户端状态”这句话。我们知道Cookie是服务器保存在客户端的信息,然后客户端会在下次请求时把Cookie在还给服务器,这样服务器就可以通过信息来识别客户端了。
2、 Cookie示例
2.1 保存Cookie到客户端
这是响应工作的一部分,所以这个方法是response对象的。并且Cookie是HTTP协议中的内容,所以保存Cookie是HttpServletResponse类的方法。
void addCookie(Cookie c):添加Cookie对象到当前response对象中,这个方法可以被调用多次,从而完成添加多个Cookie对象到response中。
Cookie cookie = new Cookie("username", "txjava");
response.addCookie(cookie);
通过浏览器的开发者工具我们可以看到,该请求的响应头中被添加了Set-Cookie的值:
同样根据浏览器的开发者工具我们可以看到http://localhost:8080的网址的cookie中被加入了username=txjava的信息:
这时我们再对服务器进行访问就会发现,访问服务器时请求时带着cookie的值的:
2.2 服务器端读取Cookie
我们现在已经可以保存Cookie到客户端了,但还没有学习让服务器如何读取Cookie。
如果浏览器保存了Cookie,那么会在下一次请求时把Cookie放到请求头中发送给服务器,这时服务器需要在请求中读取Cookie。既然是在请求中读取,那么当然是使用request对象来读取了。
HttpServletRequest:Cookie[ ] getCookies()
示例:
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie cookie : cookies){
System.out.println(cookie.getName() +":"+ cookie.getValue());
}
}
3、Cookie生命周期(熟练)
Cookie会在客户端存活多久呢?这就是Cookie的生命了。默认情况下,Cookie只在浏览器的内存中存活,也就是说,当你关闭浏览器后,Cookie就会消失!
可以使用Cookie#setMaxAge(int expiry)来设置Cookie的存活时间。参数expiry表示Cookie存活的秒数。
cookie.setMaxAge(60*60*24*30*12):表示cookie对象可存活12个月。就算关闭浏览器,就算重启客户端电脑,cookie也会存活12个月。因为当maxAge大于0时,浏览器不仅会把cookie保存在浏览器内存中,还会把cookie保存到硬盘上。
cookie.setMaxAge(-1):cookie的maxAge属性的默认值就是-1(其实只要是负数都是一个意思),表示只在浏览器内存中存活。一旦关闭浏览器窗口,那么cookie就会消失。
cookie.setMaxAge(0):cookie被作废!表示cookie即不在内存中存活,也不在硬盘上存活,这样的cookie设置只有一个目的,那就是覆盖客户端原来的这个cookie,使其作废。
4、Cookie的浏览器管理(熟练)
4.1 Google Chrom
4.1.1 查看cookie
4.1.2 清理cookie
设置-隐私设置和安全性-清除浏览数据:
4.2 Firefox
4.2.2 查看Cookie
4.2.3 清理Cookie
选项 - 隐私与安全 - Cookie和网站数据 - 清除数据
5、Cookie的路径
5.1 Cookie的path属性
Cookie还有一个path属性,可以通过Cookie#setPath(String)方法来设置。你可以使用HttpWatch查看响应中的Set-Cookie中是否存在路径。下面是通过Chrome查看Cookie信息。
也就是说,就算你不设置Cookie的path,Cookie也是有路径的。这个路径就是请求的路径。
例如
在请求:http://localhost:8080/cookie_demo/path时,服务器响应了一个Cookie,那么这个Cookie的默认路径就是/cookie_demo。
如果是在请求:http://localhost:8080/cookie_demo/path/son时,服务器响应了一个Cookie,那么这个Cookie的默认路径就是/cookie_demo/path。
5.2 Cookie 路径的作用
到现在我们还没说过Cookie的path有什么用,现在我们来聊聊path的作用。
首先声明一点,path不是指Cookie在客户端存放的路径。不同的浏览器存放Cookie的路径是不同的。你不能通过Cookie的path来指定Cookie文件的存放路径。
那么Cookie的path是干什么的呢?假设你的浏览器当前已经有了两个Cookie:
cookie1:name=path1;value=pathvalue1;path=/cookie_demo;
cookie2:name=path1;value=pathvalue2;path=/cookie_demo/path;
当访问http://localhost:8080/cookie_demo/*时,请求头中会包含cookie1,而不会包含cookie2。
当访问http://localhost:8080/cookie_demo/path/*时,请求头中会包含cookie1和cookie2。
也就是说,在访问子路径时,会包含其父路径的Cookie,而在访问父路径时,不包含子路径的Cookie。
5.3 Cookie路径的使用
如果你想在BServlet中设置的Cookie,在客户端访问AServlet时也包含在请求头中,那么就需要设置BServlet中的Cookie的path:
- c2.setPath(“/cookie_demo”):硬编码;
- c2.setPath(request.getContextpath() + “/”):活编码。
这样就可以设置Cookie的路径,保存在访问AServlet时,也会包含BServlet中添加的Cookie。
Cookie的SetPath设置cookie的路径,这个路径直接决定服务器的请求是否会从浏览器中加载某些cookie。
首先默认情况如果不设置cookie的path,默认是 /项目名称/当前路径的上一层地址
如:请求路径:/cookie_demo/servlet/login, cookie的路径:/cookie_demo/servlet
如果我们设置path,如果当前访问的路径包含了cookie的路径(当前访问路径在cookie路径基础上要比cookie的范围小)cookie就会加载到request对象之中。
6、Cookie保存中文(熟练)
6.1 Cookie中保存中文
Cookie中是不可以设置中文的,但可以使用URLEncodor.encode()方法编码后在存放到Cookie中。在获取Cookie时,需要先使用URLDecoder.decode()方法解码,再使用。
添加cookie:
Cookie cookie1 = new Cookie("username", URLEncoder.encode(username,"UTF-8"));
读取cookie:
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie cookie : cookies){
if(cookie.getName().equals("username"))
username = URLDecoder.decode(cookie.getValue(),"UTF-8");
if(cookie.getName().equals("password"))
password = cookie.getValue();
}
}
7、 Cookie的禁用
默认情况下浏览器的cookie是被启用的,但是其实我们是可以手动的禁用cookie的,强烈不建议禁用cookie。
Cookie一旦被禁用掉绝大多数互联网的网站都无法登录,这个跟我们后续要讲解的session有关。
那么我们如何通过程序来通过程序判断用户的浏览器上的cookie是否被禁用了呢,其实很简单,我们可以通过去获取刚刚添加的cookie,如果没有取到,说明cookie被禁用。
8、HttpSession概述
8.1 会话跟踪之session
session也是域对象之一,它的范围是在一个会话范围内有效。session既然是域对象,那么当然就要有getAttribute()和setAttribute()系列方法了。
在一个会话内共享一个session对象,所以session中可以保存一个会话内的数据。例如当前用户的信息。
session的范围大于request,可以在一个会话中多个请求之间共享数据。但session的范围小于ServletContext(application),session不能在多个用户之间共享数据。
目前所学过的域对象的作用范围:
ServletContext > HttpSession > HttpServletRequest
ServletContext
ServletContext
代表整个 Web 应用程序的上下文,在服务器启动时为每个 Web 应用创建一个ServletContext
对象,所有 Servlet 共享这个对象。它主要用于在整个 Web 应用的不同部分之间共享数据、获取 Web 应用的全局信息等。HttpSession
HttpSession
用于在服务器端跟踪客户端的会话状态。每个客户端访问服务器时,服务器会为其创建一个唯一的HttpSession
对象,通过会话 ID 来识别不同的客户端。它可以在用户的多次请求之间保持数据,适用于存储用户的登录信息、购物车内容等。HttpServletRequest
HttpServletRequest
代表客户端的请求,当客户端向服务器发送请求时,服务器会创建一个HttpServletRequest
对象,该对象封装了客户端请求的所有信息,如请求头、请求参数、请求方法等。
8.2 获取session对象
使用request.getSession()方法就可以获取session对象。
有了session,就不用使用Cookie来跟踪会话了!但是session不能像Cookie那样长命,一旦用户关闭浏览器窗口,那么session就死掉了。
9、HttpSession原理(依赖Cookie)
依赖 Cookie 实现会话跟踪。客户端首次访问时,服务器创建
session
对象放入session
池,并通过 Cookie 将sessionId
发送给客户端。后续客户端请求携带sessionId
,服务器据此找到对应的session
对象。
我们都知道HTTP是无状态协议,但是为什么session可以跟踪会话状态呢?没错,session依赖Cookie。
当客户端第一次访问服务器时,服务器会为客户端创建一个session对象,然后把session对象放到session池中,在响应时把sessionId通过Cookie响应给客户端。注意,只有在第一次访问时,服务器才会创建session,给客户端响应sessionId。从此以后就不会了。
当客户端再次访问服务器时,会在请求中带着sessionId给服务器,服务器通过sessionId到session池中找到session对象,这就可以完成会话跟踪了。也就是说,服务器端保存的是session对象,而客户端只有sessionId。每次访问都需要通过客户端的sessionId来匹配服务器端的session对象!这样用户在session中保存的数据就可以再次被使用了。
sessionId是服务器通过Cookie发送给客户端浏览器的,这个Cookie的maxAge为-1,即只在浏览器内存中存在。如果你关闭所有浏览器窗口,那么这个Cookie就会消失了!
10、HttpSession失效(精通)
session失效有如下几个原因:
- session.invalidate()方法注销session
- session超时
<session-config> <!-- session的超时时间,以分钟为单位 --> <session-timeout>1</session-timeout> </session-config>
- Cookie被禁用
11、请求转发和重定向
转发(Forward)和重定向(Redirect)是 Web 开发中用于页面跳转的两种常见技术,它们在实现原理、使用场景、对浏览器地址栏的影响等方面存在明显差异。
11.1 转发(Forward)
11.1.1 原理
服务器端的行为,是指在服务器内部将一个请求从一个 Servlet 或 JSP 转发到另一个资源(如 Servlet、JSP 或 HTML 页面)。在转发过程中,只有一次请求,服务器根据内部的请求调度机制将请求传递到目标资源,客户端并不知道请求被转发,整个过程在服务器端完成。
可以总结为:
- 客户端发送请求,Servlet做出业务逻辑处理。
- Servlet调用forword()方法,服务器Servlet把目标资源返回给客户端浏览器。
11.1.3 实现方式
在 Java Web 开发中,使用RequestDispatcher
的forward
方法实现转发。示例代码如下:
// 获取RequestDispatcher对象,指定转发目标资源的路径
RequestDispatcher dispatcher = request.getRequestDispatcher("/targetServlet");
// 执行转发操作
dispatcher.forward(request, response);
11.1.4 特点
地址栏不变:转发前后浏览器地址栏显示的 URL 不会改变,用户感知不到页面进行了跳转,有利于保持用户体验的一致性。
共享请求数据:由于是一次请求,转发前后的资源共享同一个HttpServletRequest
和HttpServletResponse
对象,因此可以在转发前的资源中设置请求属性,在转发后的资源中获取这些属性,方便传递数据。
只能在同一 Web应用内跳转:转发只能在同一个 Web 应用的资源之间进行,无法跳转到其他 Web 应用或外部网站。
11.1.5 适用场景
适用于需要在不同服务器端组件间传递数据,且不希望用户知道页面跳转细节的场景。如处理用户登录请求时,先由登录 Servlet 验证用户信息,再将请求转发到用户信息展示页面,在展示页面获取登录 Servlet 设置的用户信息进行展示。
11.2 重定向(Redirect)
11.2.1 原理
客户端的行为,是指服务器向客户端发送一个响应,指示客户端重新发起一个新的请求到指定的 URL。客户端收到重定向响应后,会根据响应中的新 URL 再次向服务器发起请求,这就导致了两次请求和两次响应。
11.2.2 实现方式
在 Java Web 开发中,使用HttpServletResponse
的sendRedirect
方法实现重定向。示例代码如下:
// 重定向到指定的URL
response.sendRedirect("/newPage.jsp");
11.2.3 特点
地址栏改变:重定向后浏览器地址栏显示的 URL 会变为新的请求 URL,用户能直观看到地址的变化。
不共享请求数据:重定向产生了两次独立的请求,前后的请求对象不同,无法直接共享请求属性。若要传递数据,需通过其他方式,如在 URL 中添加参数或使用session
。
可跨应用跳转:重定向可以跳转到同一 Web 应用内的资源,也能跳转到其他 Web 应用或外部网站。
11.2.4 适用场景
适用于需要引导用户到其他页面,如用户注册成功后重定向到登录页面;或当资源位置发生变化,希望用户访问新地址时。
- 操作主体与实现原理
- 转发:由服务器端操作。服务器收到请求后,通过内部的
RequestDispatcher
将请求转发到其他资源,如 Servlet、JSP 等。整个过程在服务器内部完成,客户端仅发起一次请求,不知道请求已被转发。- 重定向:属于客户端操作。服务器响应时发送 30x 状态码及新的 URL 给客户端,客户端收到后重新发起请求访问新 URL,因此会产生两次请求和响应。
- 对浏览器地址栏的影响
- 转发:地址栏 URL 保持不变,用户难以察觉页面已跳转,能维持连贯性的用户体验。
- 重定向:地址栏 URL 会更新为新请求的 URL,用户能直观看到地址变化。
- 数据共享能力
- 转发:转发前后的资源共享同一个
HttpServletRequest
和HttpServletResponse
对象,可通过request.setAttribute()
设置属性,在目标资源中用request.getAttribute()
获取,便于传递数据。- 重定向:两次请求产生不同的请求对象,无法直接共享请求属性。如需传递数据,可在 URL 添加参数或借助
session
。- 应用范围
- 转发:局限于同一 Web 应用内的资源跳转,不能跳转到其他 Web 应用或外部网站。
- 重定向:不受限制,可跳转到同一 Web应用的资源、其他 Web 应用资源或外部网站。
- 使用场景
- 转发:适用于需要传递复杂数据、保持用户操作连贯性的场景,如登录成功后,将用户信息传递到欢迎页面。
- 重定向:常用于引导用户到新页面,或资源位置变动时通知用户访问新地址,如用户注册成功后,重定向到登录页面。