1.介绍会话的过程:
首先我们要把想买的东西加购物车,放到数据库是不可能的,因为数据库存数据,是不知道哪个用户的数据,你j要知道打开京东网站,随便可以挑选商品存入购物车,不用登陆的。但是你要结算必须登陆才可以。也就是对于张三,李四客户端都是一样的。
所以这个时候的信息存入域中,我们学过两种域,一个是ServletContext,另一个是request域,假设数据存入request域,当我们想把一个手机的时候,退出去又想买电脑,两次访问资源的request不是同一个,request对象在 一次访问中就被创建一个,所以可知存到request中肯定是不行的。假设存入ServletContext域中,一个网站只有一个这种域,当不同的客户端访问这个网站的时候都往这个域中添加东西,导致滑稽现象出现。我们可以给每个客户端弄一块内存,再者,服务器不给你记录你要买的东西,让你们每个客户端自己记录。类似饭店老板让自己记着自己要的什么,结账的时候给老板报账。
因为Http协议是无状态的,也就是每个客户端访问服务器资源的时候,服务器并不知道客户端是谁,所以需要会话技术识别客户端的状态。会话记住帮助服务器区分客户端的。如果服务器给客户端记录叫做session技术,如果客户端自己记录叫做cookie技术二者的共同点都是存储客户端的数据。
会话:从打开浏览器访问一个站点,到关闭浏览器的整个过程,成为一次会话。(面试)
cookie和session的区别,cookie数据存储到客户端,减少服务器的存储压力,安全性不好,客户端可以清楚cookie,session将数据存储到服务器上,安全性好,增加服务器的存储压力。
2.Cookie的创建和发送
我要买一部手机,访问到这个资源,要加购物车,服务器给我一个响应response,将返回的信息放到响应头键值对中,当我去结算的时候我把客户端的cookie同request请求头一起发送给服务器。
所以上面的过程需要我们知道服务器如何创建一个cookie给客户端的,还要知道服务器如何再次获取客户的的cookie的。
(1)服务器端向客户端发送一个cookie
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1.创建cookie
Cookie cookie = new Cookie("name","zhongguo");
//2发送客户端cookie
response.addCookie(cookie);
}
设置cookie在客户端的持久时间,如果不设置会话时间,那cookie会存放到浏览器中,这种cookie是会话级别的;如果想改变这个时间就将cookie存放到磁盘文件。
cookie.setPath("/web16cookie_session/servlet/ServletCookie");
(2)服务器从客户端携带的cookie
getCookies() 返回值为Cookie数组
package com.itheima.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletGetCookie extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1从客户端获取cookie
Cookie[] cookie = request.getCookies();
if(cookie != null){
for(Cookie c:cookie){
String name = c.getName();
if(name.equals("name")){
String value = c.getValue();
System.out.println(value);
}
}
}
}
案例:显示用户的上次访问时间
过程:用户第一次访问服务器的时候servlet存储当前的时间,并且放在response头中送给客户端,当客户端第二次访问的时候,request头中携带这个时间,服务器可以获得用户上次的访问时间。
package com.itheima.servlet;
import java.io.IOException;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletTest1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
//response.getWriter().write("hello haohao...");
//1创建cookie
Cookie cookie_time = new Cookie("time",new Date()+"");
//2发送给客户端
response.addCookie(cookie_time);
//3.获取客户端携带的cookie
Cookie[] cookie = request.getCookies();
String value = null;
if(cookie != null){
for(Cookie c:cookie){
String name = c.getName();
if(name.equals("time")){
value = c.getValue();
//System.out.println(value);
//response.getWriter().write(value);
}
}
}
if(value == null){
response.getWriter().write("您是第一次访问该网站");
}else{
response.getWriter().write("您上次访问的时间是"+value);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
3.session技术
运行过程:session技术是基于cookie的,因为cookie用来从session的编号
客户端访问第一个servlet的时候,服务器将信息存放在服务器上的一个域中,另一个servlet可以获取,是因为这个域有编码。而这个域的编码是servlet首先知道的,他发送给客户端,客户端在携带着访问服务器的servlet资源,就把session编号传过去了。所以这个session编号就是用cookie技术实现的。这个session编码叫做jsessionid
我们要学习session技术的两个过程:第一创建session 第二向session域中存储数据 如何找这个session域也就是发送编码根据编码找到session域是客户端和服务器共同完成的,不需要我们编码。
session域比request大一些,比ServletContext小一些,所以这个session有必要学习。
request.getSession() 服务器拿到request对象,首先从里面找request是否携带了jsessionid,没有的话,在服务器上创建一个seesion区域,编码为111,同时将这个编码发送给客户端,等客户端再次访问的时候会携带这个jsessionid,tomcat检查request携带这个码,就会找到这个域,而不是创建新的。
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//获取request中的本地客户端的sessionid
/*
*request.getSession()方法首先内部会判断客户端是否在服务器端已经存在session,如果该客户端在服务器
*不存在session,那么就会创建一个新的session对象,如果该客户端在服务器端已经存有session了,就返回已*有的session
*/
HttpSession session =request.getSession();
String id = session.getId();
response.getWriter().write("jsessionid"+id);
}
session也是一个域对象,必定有三个方法,setAttribute(),getAttribute() removeAttribute()
当一次会话中,访问不同的servlet,session域中设置的内容可以访问到。
public class servlet1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//1.获取客户端在服务器端的session
HttpSession session = request.getSession();
//2.上面获取的session一定不为空
session.setAttribute("name","cs123");
}
}
public class servlet2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String value = request.getSession().getAttribute("name") + "";
response.getWriter().write(value);
}
}
3.session对象的生命周期(面试题和笔试题)
创建:第一次执行request.getSession()时创建
销毁:
(1)服务器(非正常)关闭时 (2)session过期/失效(默认30分钟) 问题:时间的起算点 从何时开始计算30分钟?
从不操作服务器端的资源开始计时,可以在工程的web.xml中进行配置
(3)手动销毁session session.invalidate();
作用范围:默认在一次会话中,也就是说在,一次会话中任何资源公用一个session对象
4.面试题:浏览器关闭,session就销毁了? 不对