一.会话技术
-
基本概念
会话就类似于正常生活中的双方打电话,有一方拿起手机,拨号,另一方接听,然后进行通话,最后结束电话,在web端,就是客户端(浏览器)发出请求,服务器收到请求,发回响应,最后关闭浏览器,在这段时间内产生的多次请求和响应,合起来就叫做浏览器和服务器之间的一次会话。
-
功能
在一次会话中的多次请求间共享数据。
比如记录用户登陆信息,有些网站在用户第一次登陆时会显示“欢迎来到本网站”,当第二次登入时,则会显示“欢迎回来”,为什么服务器能知道用户已经登录过该页面?原因就是在于服务器会话时保存了一些数据,服务器通过这些数据来判断是否登陆过,从而做出不同的响应。
-
分类
- 客户端会话技术:Cookie
- 服务器端会话技术:Session
二.Cookie
-
概述
Cookie技术是一种会话数据管理技术,是把会话数据保存在客户端的。
可以简单理解为是服务器存储在浏览器的一些数据,比如访问某一个网站时会记住用户名,当下一次访问同一个网站时候,服务器会主动去查询这个cookie,如果存在则做相关操作,比如记住密码等。
-
工作原理
Cookie的工作原理分为几步:
- 首先浏览器会向服务器发出请求
- 服务器会根据需要生成一个Cookie对象,将数据保存在该对象中。
- 然后服务器将这个Cookie对象放在响应头中,发送给浏览器
- 浏览器收到服务器响应后,将该Cookie保存在浏览器端
- 当浏览器下一次访问那个服务器时,就会把这个Cookie作为请求头一并发给服务器
- 服务器从请求头中提取出Cookie,判断里面的数据,再做相应的处理。
-
Cookie的快速使用
-
使用步骤
- 创建Cookie对象,绑定数据。使用
new Cookie(String name,String value)
- 创建Cookie对象,绑定数据。使用
-
-
发送Cookie对象。使用
response.addCookie(Cookie cookie)
- 服务器获取Cookie,拿到数据。使用
Cookie[] request.getCookies()
- 服务器获取Cookie,拿到数据。使用
首先,服务器创建Cookie,并发送给客户端
@WebServlet("/CookieServlet")
public class CookieServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 创建Cookie对象
Cookie cookie = new Cookie("name", "zhangsan");
// 发送Cookie
response.addCookie(cookie);
}
}
使用浏览器访问CookieServlet,查看响应头,此时cookie作为一个响应头发送了过来,如下图
![](https://img.haomeiwen.com/i7754744/56d2b88641250d96.png)
然后接着用浏览器再次访问服务器,查看请求头,如下图
![](https://img.haomeiwen.com/i7754744/8842a61cccdb9fa8.png)
可见,浏览器会将cookie作为请求头发送给服务器,这时服务器可以接收cookie,再做相应处理,下面加上相关代码
@WebServlet("/CookieServlet")
public class CookieServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 创建Cookie对象
Cookie cookie = new Cookie("name", "zhangsan");
// 发送Cookie
response.addCookie(cookie);
// 获取cookie
Cookie[] cookies = request.getCookies();
for (Cookie c : cookies) {
System.out.println(c.getName() + ":" + c.getValue());
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
服务器会打印出:name:zhangsan
-
Cookie常用api
-
创建Cookie对象
Cookie(String name, String value)
-
设置Cookie对象
setPath(String url)
:设置cookie的有效路径,也就是指定该cookie访问哪个资源时会发送,其他资源不会发送。setMaxAge(int expiry)
:设置cookie的有效时长,单位为秒。setValue(String newValue)
:设置cookie的值。 -
发送Cookie对象
addCookie(Cookie cookie)
-
接收浏览器的Cookie
Cookie[] getCookies()
-
-
Cookie一些细节
-
一次可不可以发送多个Cookie?
可以。创建多个cookie对象,多次使用addCookie发送即可。
-
cookie在浏览器的保存时间
默认情况下,浏览器关闭后,cookie数据被销毁;
要持久化存储,需要使用方法
setAge(int expiry)
:- 参数为正数:将Cookie数据写到硬盘的文件中,持久化存储,指定cookie的存货时间,时间到了,cookie文件会失效。
- 参数为负数:默认值,即浏览器关闭后,会销毁cookie。
- 参数为零:删除cookie数据。
-
cookie能否存储中文?
- 在tomcat 8 之前,cookie不能直接存储中文数据,需要将中文数据转码。(使用URL编码)
- 在tomcat 8 之后,cookie支持中文数据存储,但不支持特殊字符。
建议还是使用URL编码存储,再用URL解码,避免发生错误。
-
cookie共享问题
-
假设在一个tomcat服务器中,部署了多个web项目,那这些web项目中cookie能不能共享?
默认情况下是不能共享的。
如果需要共享,可以设置cookie的获取范围,使用
setPath(String path)
如果要共享,可以将path设置为'/'
-
不同tomcat服务器间cookie的共享问题。
可以使用
setDomain(String path)
,设置域名,如果设置一级域名相同,那么多个服务器之间cookie可以共享。比如:
setDomain(".baidu.com")
,那么tieba.baidu.com和news.baidu.com可以共享cookie。
-
-
-
cookie的特点和作用
- 特点
- cookie存储在客户端浏览器中。
- 浏览器对于单个cookie的大小有限制,最大为4kb。
- 同一域名下的总cookie数量有限制,最大为20个。
- 作用
- 一般用于存储少量,不太敏感的数据。
- 可以完成对客户端的身份识别
- 特点
-
小程序——记录上次访问的时间
需求:访问一个servlet,如果是第一次访问,则提示"你好,欢迎来到本网站",如果不是第一次访问,则提示"欢迎回来,您上次访问时间为:xxxxx"
@WebServlet("/CookieTest") public class CookieTest extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置编码 response.setContentType("text/html;charset=utf-8"); boolean flag = false; // 获取Cookie Cookie[] cookies = request.getCookies(); if (cookies != null && cookies.length > 0) { for (Cookie c: cookies) { if (c.getName().equals("lastTime")) { flag = true; // 不是第一次登录,设置当前时间,重新发送cookie Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String str_date = sf.format(date); // URL编码,避免乱码 str_date = URLEncoder.encode(str_date, "utf-8"); c.setValue(str_date); // 设置Cookie存活时间 c.setMaxAge(60 * 60 * 24 * 7); // 一周 // 发送cookie response.addCookie(c); // 响应部分 String value = c.getValue(); value = URLDecoder.decode(value, "utf-8"); response.getWriter().println("<h1>欢迎回来,上次访问时间为:" + value + "</h1>"); break; } } } // 第一次访问 if(cookies == null || cookies.length == 0 || flag == false) { // 设置Cookie Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String str_date = sf.format(date); // 编码 str_date = URLEncoder.encode(str_date, "utf-8"); Cookie cookie = new Cookie("lastTime", str_date); // 设置存活时间 cookie.setMaxAge(60*60*24*7); response.addCookie(cookie); // 响应 response.getWriter().println("<h1>您好,欢迎首次访问</h1>"); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
执行结果如下:
第一次访问时:
![](https://img.haomeiwen.com/i7754744/eadfc2e3479400f5.png)
第二次访问:
![](https://img.haomeiwen.com/i7754744/2aaf9b6a41073ef6.png)
三.Session
-
概述
Session是另一种会话管理技术,Session将数据保存在服务器端。
Session和Cookie同样是会话管理技术,但一般使用Session,主要是Cookie存在以下局限性:
- Cookie的数据类型是String的,而且大小由限制
- Cookie不适合存储敏感数据
而Session可以解决以下两个问题。
-
工作原理
Session的实现是依赖于Cookie的。
Session工作分为以下几步:
- 浏览器发送请求到服务器。
- 服务器会根据需要生成Session对象,并且给这个对象一个ID,一个ID对应一个Session对象。
- 服务器把数据封装到这个Session对象,然后把Session对象保存在服务器端。
- 服务器将Session对象的ID,存放到Cookie中,作为响应发给浏览器
- 浏览器接收到这个Cookie,会保存起来,下一次请求服务器时,会将这个Cookie作为请求头发给服务器。
- 服务器拿到这个Cookie后,取出内容,就是Session对象的ID,然后通过这个ID找到Session对象,取出数据。
-
Session的相关API
-
获取HttpSession对象
HttpSession session = request.getSession()
-
使用HttpSession对象
Object getAttribute(String name)
void setAttribute(String name, Object value)
void removeAttribute(String name)
-
其他
获取Session对象的ID:
String getId()
设置session对象的有效时间:
void setMaxInactiveInterval(int interval)
销毁session对象:
void invalidate()
-
-
Session的一些细节
-
当客户端关闭后,服务器不关,两次获取的Session是否同一个?
默认情况下不是同一个。
如果需要是同一个,则可以通过创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化存储。
因为session的实现是依赖于cookie的,并且cookie中保存的是session的id。
-
客户端不关闭,服务器关闭后,两次获取的session是否同一个?
不是同一个。
但为了确保数据不丢失,tomcat会自动完成以下工作:
- session的钝化:在服务器正常关闭之前,将session对象系列化到硬盘上
- session的活化:在服务器启动之后,将session文件转化为内存中的session对象
(IDEA不支持这种操作,因为每次用idea重启tomcat时候,会自动删除catalina_base中的work目录,这样session的序列化文件会被删除)
-
Session什么时候被销毁?
-
服务器关闭
-
session对象调用invalidate()
-
session默认失效时间:30分钟
选择性配置修改web.xml
<session-config> <session-timeout>30</session-timeout> </session-config>
-
-
-
session的特点
- session用于存储一次会话的多次请求的数据,数据保存在服务器端
- session可以存储任意类型,任意大小的数据
-
Session与Cookie的区别
- session数据存储在服务器端,cookie数据存储在客户端
- session没有数据大小限制,cookie有
- session数据安全,cookie相对不安全
-
Session小练习
-
需求
使用session实现记录上次访问的时间,需求与Cookie中的练习一致。
-
代码实现
@WebServlet("/SessionTest") public class SessionTest extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 设置编码 response.setContentType("text/html;charset=utf-8"); // 获取session HttpSession session = request.getSession(); if (session != null && session.getAttribute("Last_Time") != null) { // 不是第一次登录,设置当前时间, Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String str_date = sf.format(date); // URL编码,避免乱码 str_date = URLEncoder.encode(str_date, "utf-8"); session.setAttribute("Last_Time",str_date); // 响应 String value = (String)session.getAttribute("Last_Time"); value = URLDecoder.decode(value, "utf-8"); response.getWriter().println("<h1>欢迎回来,上次登录时间为:" + value + "</h1>"); } else { // 第一次登录 Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String str_date = sf.format(date); // URL编码,避免乱码 str_date = URLEncoder.encode(str_date, "utf-8"); session.setAttribute("Last_Time",str_date); // 响应 String value = (String)session.getAttribute("Last_Time"); value = URLDecoder.decode(value, "utf-8"); response.getWriter().println("<h1>您好,欢迎首次登录</h1>"); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }
-
网友评论