会话技术
什么是会话技术
在日常生活中,从拨通电话到挂断电话之间的一连串的你问我答的过程就是一个会话。Web应用中的会话过程类似于生活中的打电话过程,它指的是一个客户端(浏览器)与Web服务器之间连续发生的一系列请求和响应过程,例如,一个用户在某网站上的整个购物过程就是一个会话。
简而言之:从用户访问网站开始到离开网站,关闭浏览器,这个过程就叫会话。
**注意:**每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,程序要想办法为每个用户保存这些数据。Servlet在会话过程中保存数据使用到的技术有两种:Cookie技术和Session技术。
小结
- Cookie和Session技术都是在会话期间产生的 ;
- Cookie和Session的作用都是保存数据 ;
Cookie是什么
Cookie是什么
Cookie英文意指饼干,Cookie就是服务器暂存放在我们电脑上的一笔资料(where?打开浏览器),使用我们电脑来保存一些服务器希望保存的内容。Cookie是由服务器端生成,发送给浏览器,浏览器会将Cookie以key/value
形式的数据保存到某个目录下的文本文件内,下次请求同一网站时就会将该Cookie发送给服务器。当然前提是浏览器设置了启用cookie。
Cookie作用:减轻服务器保存数据的压力。
问题:我们发现将数据保存在浏览器中?而不是保存到服务器或者数据库中?
将数据保存到服务器中,会增加服务器的压力。同时,如果用户不进行购买,并没有带来经济利润。存储到数据库中,如果没有登录到网站,那么将无法查询出数据。而存储到浏览器中可以减轻服务器端压力,并且用户不用登陆也可以将商品添加到购物车中。
关于cookie介绍如下图所示:
Cookie的基础API
Cookie的API介绍
Cookie的基本API包括Cookie的创建,往Cookie中添加数据,获取Cookie中的数据以及将Cookie响应给浏览器。
方法 | 使用示例 | 说明 |
---|---|---|
创建Cookie对象 | Cookie(String name,String value)name表示指定 cookie 名称 ,value 表示指定 cookie 值 | Cookie c1 = new Cookie(“username”,“suoge”) |
获取cookie的name值 | String getName() | c1.getName() |
获取cookie的value值 | String getValue() | c1.getValue() |
设置cookie的值 | void setValue(String value) | c1.setValue(“李四”) |
说明:上述都是该案例中需要的Cookie类中的API.但是该案例除了需要上述API,还需要如下API:
1、HttpServletResponse接口中的方法:
void addCookie(Cookie cookie) 将cookie发送给浏览器
示例: response.addCookie(Cookie对象);
2、HttpServletRequest接口中的方法:
Cookie[] getCookies() 获取浏览器发送的cookie
示例: Cookie[] cookies = request.getCookies();
小结
-
创建Cookie
-
Cookie c1 = new Cookie("key","value");
-
-
给浏览器发送Cookie
-
response.addCookie( c1 );
-
-
获取浏览器请求中的Cookie
-
Cookie[] cookies = request.getCookies();
-
-
操作Cookie中的数据
-
c1.getValue(); c1.getName(); //修改cookie中的value c1.setValue("修改的值");
-
Cookie存储特殊字符
在Cookie中不能存储特殊字符。例:空格、分号、逗号等
-
记住:为了方便存储,把Cookie中的value数据进行编码操作
-
当要存储特殊字符时,在存储到Cookie之前进行:编码操作
-
String 编码后的数据 = URLEncoder.encode("数据","编码表名称");
-
-
从浏览器的请求中获取到Cookie对象后,在获取Cookie的value值之后进行:解码操作
-
String 解码后的数据 = URLDecoder.decode("Cookie中的数据","编码列名称");
切记:编码和解码操作时编码表名称必须保护一致
-
Cookie的存活时间
Cookie的默认存活时间
在上面的案例中我们发现,将浏览器关闭。然后再打开一个新的浏览器,查看浏览器中的cookie,发现之前保存的cookie都消失了。我们再次登录发现之前设置的Cookie的到期时间为"浏览器会话结束"。
如果,我们想让这个cookie在浏览器关闭后能够在一段时间内都存在,比如记住用户名或密码一周。我们可以通过设置Cookie的最大存活时间来对这个Cookie进行设置。
结论: Cookie会话默认的存活时间为浏览器会话结果(关闭浏览器Cookie也随之销毁)
【Cookie级别】
- 会话级别 的Cookie:浏览器关闭后消失;
- 持久化 的Cookie:浏览器关闭后能够保存一段时间;具体的时间可以使用相关API进行设置。
注意:如果没有设置Cookie的保存时间,那么Cookie就是会话级别的Cookie。
Cookie的最大存活时间
设置Cookie的最大存活时间的方法是:
方法 | 使用示例 | 说明 |
---|---|---|
void setMaxAge(int seconds) | userNameCookie.setMaxAge(60*60); 设置存活时间是1小时。 | 设置Cookie的有效时间,单位是秒: 如果没有设置,cookie只会保存在浏览器的缓存中,浏览器关闭后cookie立即被删除。 如果设置有效时间,在时间范围内,cookie被写入到浏览器端,关闭浏览器下次访问仍可活的,直到过期。 |
Cookie的有效路径
Cookie的有效路径
当我们访问某个商城网站的时候,由于商城网站会分为多个部分,例如包含用户模块、商品模块等。那么当我们访问用户模块我们希望请求携带的是用户的cookie,而不需要商品的cookie。但是按照我们之前的做法,只要访问服务器,那么所有的cookie都会被携带到服务器中,这并不符合我们开发中的需求。所以我们接下来要学习Cookie的有效路径,只要设置了Cookie的有效路径就可以解决访问哪个模块就携带哪个模块的Cookie。
说明:Cookie的有效路径指的是Cookie允许被访问的路径。设置路径,以及子路径都被允许访问。方法如下:
方法 | 使用示例 | 说明 |
---|---|---|
void setPath(String path) | cookie.setPath(“/suoge”) cookie.setPath(“/”) | cookie.setPath(“/suoge”):指的是/suoge路径及其子路径可以访问这个cookie,例如:/suoge/a/b/c都可以访问; cookie.setPath(“/”)指的是当前tomcat下的所有的web项目都可以访问这个cookie。如果代码中不进行有效路径的设置,那么就是默认的路径/,即tomcat下的所有的web项目都可以访问这个cookie; |
【idea控制台效果】:
idea的控制台中并没有获取到之前的cookie中的path。
当给cookie设置有效路径"/suoge/a/b"后:
- 访问路径:/suoge 获取不到cookie;
- 访问路径:/suoge/a/b/d 能获取到cookie ;
- 访问路径:/suoge/a/b 能获取到cookie ;
- 访问路径:/suoge/a/d 获取不到cookie;
【结论】
- 当设置cookie的有效路径后,只能在有效径或其子路径下访问这个cookie;
- 如果不给cookie设置有效路径,默认的有效路径为"/" ,即在当前tomcat下的任意访问路径均可获取这个cookie;
Cookie删除
Cookie删除的方式
通常情况下,如果浏览器中的cookie存储的太多,我们要对浏览器中的cookie进行删除。删除浏览器中的cookie有以下几种方式:
-
在浏览器中手动删除cookie;
-
等待设置cookie的时间到,自动删除;
-
使用代码来删除:Servlet中没有专门提供API去删除cookie。可以通过置换或者替换方式删除cookie
代码实现Cookie删除
【操作步骤】
- 创建与要删除的cookie同名的cookie,将其值设置成""
- 将这个cookie的最大存活时间设置成0
- 设置这个cookie的有效路径(与原cookie的有效路径一致)
- 将这个新的cookie响应给浏览器,置换原来的cookie
让cookie消失的几种方法
- 没有设置最大存活时间的cookie,浏览器关闭后cookie立即消失;
- 使用浏览器手动清除cookie;
- 浏览器禁用cookie;
- 通过Servlet技术将cookie删除
- 1、创建相同key的Cookie对象
- 2、保证Cookie有效路径相同
- 3、设置Cookie的时间为0
- 4、把Cookie响应给浏览器
- 设置等待设置的时间到,自己消失。
Session概述
Cookie会话技术的弊端是数据的不安全性。而在开发中对于存储的数据安全性有极高要求的则不能使用cookie技术来存储。例如登录网站之后,用户的用户名和密码就不能存储在cookie中,而需要存储在另一个会话技术session中
Session是什么
Session是服务器为每个访问这个服务器的客户端用户创建的一个容器(这个容器只属于当前这个用户)。这个容器中存储的数据能够在多个request之间实现共享
Session的作用
-
为每个访问服务器的用户创建一个存储数据的容器
-
容器中的数据在多个请求之间共享
-
整个会话过程中,所有的servlet都可以共享session中的数据
-
session属于域对象,整个会话过程中,可以向其中存储数据,在其他servlet中获取数据
Session的原理
表面上,我们说Session容器是属于某一个用户。其实在会话过程中,只有客户端(浏览器)和服务器两个角色。所以,Session容器标识的不是用户,而是当前用户正在使用的浏览器。浏览器与服务器交流是通过给服务器发送请求实现的,浏览器的每次请求中如果都有一个相同的标记用来标记session。服务器就能够识别这个用户了。这个标记叫做JSESSIONID
Session是服务器端的会话技术,可以实现多个request请求之间的数据共享
Session也是一个域对象
域对象的使用范围:
-
request : 2个servlet,使用在转发。一次请求
-
servletContext:全局。整个web项目,可以读取配置文件中的数据
-
session:整个会话过程中的所有的servlet之间
servletContext > session > request
Session容器创建和销毁的API
Session的API介绍
创建Session对象
//创建session 如果session不存在,创建session,存在,获取当前session
request.getSession();
request.getSession(boolean);
HttpSession session1 = request.getSession(true);
//两个API效果相同 request.getSession(true); 等于 request.getSession();
//创建session 如果session不存在,创建session,存在,获取当前session
request.getSession(false);
//如果当前存在session 获取当前session, 不存在,不获取session,返回null
销毁Seesion对象
session.invalidate() //使当前session失效,即销毁当前session
获取Session的唯一标记id
String sessionId = session.getId(); //获取session的唯一标识id
补充知识:Session的其他API
HttpSession接口方法 | 作用 |
---|---|
long getCreationTime() | 表示会话创建的时间,返回long类型。 表示1970-1-1到这个时间之间相差的毫秒数 |
boolean isNew() | 判断当前是否是一个新的会话,是的返回true |
Session域对象的API
Session域对象API介绍
由于session属于域对象,所以Session其他的常用API包括:往session容器中存储数据,删除数据,获取数据。
方法 | 使用示例 | 说明 |
---|---|---|
void setAttribute(String name,Object value) | session.setAttribute(“loginUser”,user) | 将一个对象与一个名称关联 之后存储到session中 |
Object getAttribute( String name) | session.getAttribute(“loginUser”) | 通过名称获取session 中的数据 |
void removeAttribute(String name) | session.removeAttribute(“loginUser”) | 根据指定名称删除 session中的数据 |
Session的生命周期(了解)
创建Session
当客户端浏览器第一次访问服务器时,服务器为每个浏览器创建不同的HttpSession对象。在服务器端使用request.getSession()方法来获得HttpSession对象。
当第一次执行 request.getSession()是session对象就被创建了。后续的request.getSession()只能获取已创建的session。
销毁Session
方式一:tomcat服务器非正常关闭(例如电脑电源突然断电)【了解】
方式二:时间超出了session的存活时间
session的默认存活时间是30分钟,在tomcat的全局配置文件web.xml中。(路径:tomcat/config/web.xml)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-krE4DZ9N-1651023902478)(imgs/1530064946331.png)]
我们可以在web.xml中自己设置这个存活时间。我们设置的这个时间会覆盖原来的存活时间。
【注意】
注意:30分钟从什么时候开始计算?
从用户最后一次访问时间开始计算:
Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session"活跃(active)"了一次。
**注意:**开发中一般我们将session设置为30分钟,所以没有必要对session的存活时间进行设置。这个知识点了解就好了。
如果想手动配置session的存活时间,可以将session-config这段配置复制到自己项目中的web.xml中。就可以修改session的存活时间了
【web.xml配置】
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--将session的存活时间设置成50-->
<session-config>
<session-timeout>50</session-timeout>
</session-config>
</web-app>
方式三:立即销毁
HttpSession方法 | 功能描述 |
---|---|
invalidate() | 会话立刻失效,一般用于用户退出,注销 |
方式四:手动设置过期时间
如何在服务器上查看session的销毁时间?
查看Session的销毁时间:
session中的方法 | 说明 |
---|---|
int getMaxInactiveInterval() | 得到服务器上会话最大的非活动时间间隔,默认是1800秒(30分钟) |
【注意】
时间间隔的含义:如果你在这段时间内再次发送请求给服务器,服务器将会重新计时。
手动设置Session的过期时间:
HttpSession的方法 | 功能描述 |
---|---|
void setMaxInactiveInterval(int 秒) | 设置会话最大非活动时间时隔,单位是秒 |
浏览器关闭后Session持久化方案
关闭浏览器后Session的状态
通过上面的学习,我们已经知道在服务器创建session的过程中同时生成一个jsessionid和一个cookie,将jsessionid存储到cookie中,然后响应到浏览器中,当下次访问服务器的时候会将cookie中的jsessionid取出到服务器中找对应的session。那么现在会有2个问题,cookie属于什么级别的呢?如果cookie消失,还可不可以找到对应的session?
答案:首先服务器创建的cookie属于会话级别的cookie,即把浏览器关闭,cookie就会消失,由于jsessionid存储在cookie中,也会随着消失,下次打开浏览器在访问服务器的时候就找不到对应的session了,服务器又会重新创建一个新的session容器。那么如果多次创建session并且多次关闭浏览器就会在服务器端产生多个无用的session,会占服务器的资源,服务器性能降低。
补充:session在服务器中的存活时间默认是30分钟。30分钟之后才可以消失。不是浏览器关闭了就消失。
Session持久化方案
使用session持久化方案可以解决上述问题。我们只需要把会话级别的cookie变为持久化级别的cookie,那么就可以解决了。建议让cookie存活时间也是30分钟,和session存活时间一致。
【实现方案】:
1. 在Servlet中创建session并获取JSESSIONID;
2. 创建Cookie对象,将上述从session中获取的JSESSIONID放到cookie中;
3. 手动设置存放JESSIONID的cookie的存活时间为30分钟;
4. 将存放JESSIONID的cookie响应给浏览器;
原理图: