会话概述
会话:用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应
会话跟踪:维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据
服务器是不知道某几个请求是否是来自于同一个浏览器的,因为:HTTP协议是无状态
的(为了保证每次请求都很快),每次浏览器向服务器请求时,服务器都会将该请求视为新的请求,因此我们需要会话跟踪技术来实现会话内数据共享
实现方式:
1.
客户端会话跟踪技术: Cookie
2.
服务端会话跟踪技术: Session
Cookie
基本使用
它是客户端的会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问
演示实验:
我们首先创建一个demo servelet来给客户端发送cookie:
@WebServlet(value = "/CookieDemo1")
public class CookieDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建cookie对象
Cookie cookie = new Cookie("username", "test-name");
//发送cookie对象到客户端
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
随后我们启动服务,在浏览器中访问这个资源
这时我们可以在当前网页发现cookie已经发送过来了
我们发送cookie的实验已经完成,接下来创建第二个资源来接受cookie,将第一个servlet的cookie显示在我们服务端的控制台上:
@WebServlet(value = "/CookieDemo2")
public class CookieDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//接受cookie
Cookie[] cookies = req.getCookies();
//按照name来将cookie取出
for (Cookie cookie: cookies) {
String userName = cookie.getName();
if (userName.equals("username")){
String value = cookie.getValue();
System.out.println(userName+":"+value);
break;
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
随后我们在浏览器中访问CookieDemo2这个资源
我们能够发现在控制台输出了我们刚刚在CookieDemo1中发送给客户端的Cookie,完成了两次请求之间的资源共享
原理
Cookie的实现是基于HTTP协议的
●响应头: set-cookie
●请求头: cookie
过程描述:
我们的servlet发送数据给浏览器的时候,发现我们要发送的数据是一个Cookie,那么它就将set-cookie我们这个对应的Cookie放到响应头中发送给客户端浏览器,浏览器存储在本地。当浏览器在本次会话想要访问第二个资源的时候,就会在请求头中带上自己当前的这个Cookie消息由cookie消息头发送给服务器。
还是之前的两个资源,我们访问一下,可以在第一个资源的响应头中看到set-cookie
在第二个资源的请求头中看到cookie
细节
存活时间
- 默认情况下, Cookie 存储在浏览器内存中,当浏览器关闭,内存释放,则Cookie被销毁
- setMaxAge(int seconds):设置Cookie存活时间
1.正数:将Cookie写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除
2.负数: 默认值, Cookie在 当前浏览器内存中,当浏览器关闭,则Cookie被销毁
3.零:删除对应Cookie
存储中文
- Cookie不能直接存储中文
- 如需要存储,则需要进行转码: URL编码
Session
基本使用
演示:
我们在demo1中设置session来存储数据:
@WebServlet(value = "/SessionDemo1")
public class SessionDemo1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取session对象来存储
HttpSession session = req.getSession();
//利用session对象存储键值对
session.setAttribute("username","test");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
然后我们用demo2来获取服务器中session对象的值
@WebServlet(value = "/SessionDemo2")
public class SessionDemo2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取Session对象
HttpSession session = req.getSession();
//获取值
Object username = session.getAttribute("username");
System.out.println(username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req,resp);
}
}
代码写好之后,我们在我们的浏览器中,先访问SessionDemo1,再访问SessionDemo2,在服务端得到的结果如下:
原理
Session是基于cookie实现的(因为Session要基于Cookie来保证在一次会话的不同请求之间保证是同一个Session)
当某个请求访问到服务器时,如果我这时候创建的了session,那么Tomcat发现了我使用了session对象,那么会在返回给客户端的响应消息中加上一个set-cookie = id
,这个id就是我们这个session的唯一标识码。然后当我们在当前会话再次请求其他资源的时候,本地浏览器发送的请求头就会带着cookie = id
去访问服务器的资源