1.什么是会话
从打开一个浏览器访问某个站点,到关闭这个浏览器的整个过程,成为一次会话。会话技术就是记录这次会话中客户端的状态与数据的。
会话技术分为Cookie和Session:
Cookie:数据存储在客户端本地,减少服务器端的存储的压力,安全性不好,客户端 可以清除cookie
Session:将数据存储到服务器端,安全性相对好,增加服务器的压力
session基于cookie技术,session内存区域借助于cookie存储内存编号id
2.Cookie和session的比较
Cookie和session的存储数据的共同点:都是会话技术,只要客户端的cookie被清空,数据就找不到了
Cookie:
1.数据保存在浏览器
2.数据不安全
Session:
- 数据保存在服务器
2.依赖于cookie
3.会造成服务器压力过大
4.安全性好
3.1 cookie的使用
服务器向客户端发送Cookie时,会在HTTP响应头字段中增加Set-Cookie响应头字段。Set-Cookie头字段中设置的Cookie遵循一定的语法格式,具体示例如下:
Set-Cookie: username=itcast; password=123;
在上述示例中,username表示Cookie的名称,itcast表示Cookie的值。需要注意的是,Cookie必须以键值对的形式存在,其属性可以有多个,但这些属性之间必须用分号;和空格分隔。
了解了Cookie信息的发送方式后,接下来,通过一张图来描述Cookie在浏览器和服务器之间的传输过程,具体如图5-1所示。
5-1Cookie在浏览器和服务器之间传输的过程
在图5-1中,描述了Cookie在浏览器和服务器之间的传输过程。当用户第一次访问服务器时,服务器会在响应消息中增加Set-Cookie头字段,将用户信息以Cookie的形式发送给浏览器。一旦用户浏览器接受了服务器发送的Cookie信息,就会将它保存在浏览器的缓冲区中,这样,当浏览器后续访问该服务器时,都会在请求消息中将用户信息以Cookie的形式发送给Web服务器,从而使服务器端分辨出当前请求是由哪个用户发出的。
3.2cookie的使用
流程分析:
步骤分析:
步骤一:浏览器发送请求
步骤二:服务器生成cookie并且响应cookie
步骤三:浏览器自动保存cookie
步骤四:浏览器再次发送请求时请求头中会携带cookie (不管第二次请求是servlet还是页面)
代码实现:
public class DemoCookie1 extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
/**
* 生存时间(重要)
* 默认情况下,cookie的生存时间是浏览器关闭就消失。
* cookie生存时间的设置 cookie.setMaxAge(int seconds);
*
*
* cookie路径的问题:(了解)
* 默认情况下,cookie访问同级或者下级目录都会携带cookie
* setPath();设置cookie的携带路径
* setPath("/");服务器内容携带,一般不设置
* setPath("/web05"); 当前项目内所有的路径都携带该cookie
*
*
* cookie的唯一标示
* 域名+path+cookie名
*
*
* cookie的删除
* cookie删除的本质:使用一个空的cookie去替换原有的cookie
* 1.cookie的唯一标识需要与被删除的cookie的唯一标识一致
* 2.使用空的cookie去替换原有的cookie。cookie的值为空
* 3.设置cookie的生存时间为0
*/
String str = "中文";
str = URLEncoder.encode(str, "utf-8");
System.out.println("转换后的中文:"+str);
//第一步创建cookie对象
Cookie cookie = new Cookie("username",str);
//设置cookie的生存时间
cookie.setMaxAge(60*30);
//设置cookie的路径,设置当前项目内所有的路径都携带cookie
cookie.setPath("/web05");
//第二步将cookie响应给浏览器
response.addCookie(cookie);
Cookie cookie1 = new Cookie("age","18");
response.addCookie(cookie1);
}
}
测试:response在响应的时候把cookie作为一个响应头,响应给客户端。
当客户端再次发送请求到servlet时:发现第二次请求时把cookie携带到服务器端了
注意:cookie中不能存储中文
//cookie中存储中文的话,需要对中文编码,然后获取cookie中的数据的时候再进行解码
提示:chrome、firefox清除缓存和cookie的快捷键shift+ctrl+delete(清理缓存有时比较慢,等一会才起作用)
3.3 cookie的生存时间
Cookie的生存时间可以进行设置,如果不设置,那么默认的生存时间就是一次会话的时间。
3.3.1Cookie默认生存时间
【示例】
测试cookie默认的生存时间:浏览器关闭cookie消失
步骤一:创建一个新的Servlet
public class SendCookie2Servlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//创建cookie
Cookie cookie = new Cookie("sex","female");
//cookie的默认的生存时间是一次会话(即关闭浏览器后cookie消失)
response.addCookie(cookie);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
web.xml
<servlet>
<servlet-name>send2</servlet-name>
<servlet-class>cn.itcast.cookie.SendCookie2Servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>send2</servlet-name>
<url-pattern>/send2</url-pattern>
</servlet-mapping>
步骤二:发送请求进行测试:
步骤三:再次发送请求:
步骤四:重启浏览器后,发送请求
原因:cookie是存储于浏览器的内存中,一旦浏览器关闭,数据就被清空了。
因此cookie的默认作为范围是一次会话。
3.3.2Cookie生存时间的设置
【示例】
设置cookie的生存时间
步骤一:修改代码
步骤二:重启浏览器后再次发送请求
Expires:指的是到期时间。在这个时间上+8个小时就是cookie的到期时间。
3.4 获取cookie
通过httpServletRequest获取cookie:
遍历cookie数组获取key和value
通过cookie获取key:
通过cookie获取value:
步骤一:编写获取cookie的servlet
public class DemoCookie2 extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
/**
* request.getCookies();获取当前请求中的所有的cookie,返回值是一个cookie的数组,如果请求中么有cookie会返回null
*/
Cookie[] cookies = request.getCookies();
if(cookies!=null){
for (Cookie cookie : cookies) {
//cookie的名字
String name = cookie.getName();
String value = cookie.getValue();
//如果cookie要存储中文,需要先转后解
value = URLDecoder.decode(value, "utf-8");
System.out.println(name+":"+value);
}
}
}
}
步骤二:请求http://localhost:8080/web_day05/send
发送请求,响应cookie.
步骤三:发起请求http://localhost:8080/web_day05/get
发送请求到GetCookieServlet获取cookie
3.5 删除cookie
如何删除cookie?
删除cookie必须满足如下条件:(原理,就是用一个空的新的cookie覆盖原有的cookie)
1、创建一个相同key的cookie,值为””
2、,然后将生存时间设置为0。
3、在删除cookie时必须将步骤1中创建的cookie的path设置成和需要删除的cookie的path一致。
必须将cookie.setPath(String path);中的path设置成和要删除的cookie的path一致。
只有相同path的cookie才算同一个cookie。
推荐使用firefox进行测试,chrome可能显示不出效果
【示例】
删除SendCookie2Servlet中生成的cookie
步骤一:创建一个删除cookie的servlet
//清除cookie
Cookie cookie = new Cookie("username", "");
Cookie cookie2 = new Cookie("password", "");
cookie.setMaxAge(0);
cookie2.setMaxAge(0);
//响应给浏览器
response.addCookie(cookie);
response.addCookie(cookie2);
步骤二:浏览器发送请求访问SendCookie2Servlet
步骤三:浏览器发送请求访问DeleteCookieServlet
注意:如果使用chrome测试的话,可能在第一次请求delete的时候就已经没有cookie了,因此建议使用火狐进行测试。
在响应cookie的时候name=“”。
而请求头中还有sex=female,那是请求先执行的请求,因此cookie还没有被删除,当再次发送请求到DeleteCookieServlet时,该cookie就会被删除
步骤三:再次发送请求
4.1 Session的使用
Session技术是将数据存储在服务器端的技术,会为每个客户端都创建一块内存空间存储客户的数据,但客户端需要每次都携带一个标识ID去服务器中寻找属于自己的内存空间。所以说Session的实现是基于Cookie,Session需要借助于Cookie存储客户的唯一性标识JSESSIONID
流程分析:
获取session:
HttpSession session = request.getSession();
此方法会获得专属于当前会话的Session对象,如果服务器端没有该会话的Session 对象会创建一个新的Session返回,如果已经有了属于该会话的Session直接将已有的Session返回
因此:第一次访问servlet时创建,第二次访问就是获取。
Session是会话级别的,因此如果是不同的浏览器获取的session肯定不是同一个session
步骤一:创建servlet获取session;
public class DemoSession1 extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//获取session,
/**
* session是一个域对象
* setAttribute(key,value);
* getAttribute(key);
* removeAttribute(key);
*
*
* session的生存时间:默认情况下是30分钟。从最后一次访问项目开始算起。
* web.xml中的配置设置 session的生存时间
* <session-config>
<session-timeout>30</session-timeout>
</session-config>
关闭浏览器,30分钟不到的情况下,再次访问服务器;发现获取的并不是同一个session;
这是因为我们保存session的id的cookie默认情况下,浏览器器关闭就销毁了。
解决方法:设置保存sessionid的cookie持久化就行了。
*/
HttpSession session = request.getSession();
//设置保存sessionid的cookie持久化
// Cookie cookie = new Cookie("JSESSIONID", session.getId());
// //持久化cookie
// cookie.setMaxAge(60*60);
// response.addCookie(cookie);
Random rd = new Random();
int value = rd.nextInt(200);
//向session中存储数据
session.setAttribute("username", value+"");
System.out.println("session中 存储数据:"+value+"=======sessionid是:"+session.getId());
}
}
步骤二:访问测试
问题:如果再创建一个servlet进行访问,从该servlet中获取的session和id表示是同一个吗
步骤三:再次创建一个servlet
public class DemoSession2 extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//获取session中的数据
HttpSession session = request.getSession();
String username = (String)session.getAttribute("username");
System.out.println("从session中获取的数据是:"+username+"====sessionid是:"+session.getId());
}
}
步骤四:访问Session2Servlet
结果证明是同一个id标识
4.2 Session存取数据
Session存储数据:
Session获取数据:
获取key的枚举类型:
删除session中的数据:
4.3 Session的生命周期
-
什么时候开始执行
当第一次执行HttpSession session = request.getSession();时开始。(不能清空session) -
什么时候结束
1)当服务器被非正常关闭
如果正常关闭服务器,session的信息,会被序列化硬盘中,保存在tomcat的work\Catalina\localhost\web_day05,当tomcat下一次启动的时候,会把session加载回来。序列化的文件会被销毁2)超过设置的session的生存时间
由于会有越来越多的用户访问服务器,因此Session也会越来越多。为防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了。
Session的生存时间默认为30分钟,在tomcat的web.xml中有默认设置:
注意:30分钟从什么时候开始计算?
从用户最后一次访问时间开始计算:
Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session"活跃(active)"了一次。
-
在程序执行中,手动销毁session对象,session.invalidate();
注意:关闭浏览器仅仅是丢失session的id标识(即JSESSIONID,存储于cookie中,而cookie如果不手动设置生存时间,那么默认就是会话级别,关闭浏览器就没了)从而导致找不到session,但是session本身还是存在的。
【示例】
思考:如果将浏览器重启,然后再次发送请求到Session2Servlet,能否从session中获取数据?session是否还存在?
答:session虽然还存在,但是session是通过JSESSIONID来找到sesssion的,而JSESSION其实就是一个cookie,而cookie的默认生存时间是一次会话,因此到浏览器重启之后,cookie就没有了,因此也就无法通过cookie中的JSESSIONID来获取session.
解决方案:设置cookie的生存时间,将cookie持久化到客户端即可。
1、获取JSESSIONID(大小写敏感)
2、设置生存JSESSIONID的生存时间
3、响应JSESSIONID