会话技术简介
会话是指一个==终端用户与交互系统进行通讯的过程==,简单理解就是当一个浏览器发送请求到服务端之后,就会建立一个会话,如果浏览器和服务端都没有关闭的情况下,此会话会一直存在,直到任何一方关闭此会话才会结束。
一个会话中可以存在多次请求,比如说,当我们打开浏览器访问一个购物网站时,那么此时会话已经建立,你在这个网站中所有的操作其实都是在这次会话中完成,如加入购物车,购买商品等,只要浏览器和服务端没有任何一端关闭,会话就一直存在。
会话的作用
数据共享
HTTP请求是一个无状态请求,也就是说每当一个请求结束之后,这个请求就会彻底断开,所以每个请求服务端都会视为新的请求,但是一个会话中可以存在多个请求,那么如果我们能判断当前一个会话中的所有请求,其实我们就可以通过会话技术Cookie、Session来完成数据共享了。
当然Cookie和Session的最大区别在于,Cookie是存储在客户端,Session是存储在服务端。
Cookie
Cookie本身存在于客户端。
基本概念
-
Cookie 是在浏览器访问web服务器上的某个资源时,由web服务器在响应浏览器时通过响应头附带的传送给浏览器并存储在浏览器端的一小段数据
-
一旦web浏览器保存了来自某个服务器的Cookie,那么当浏览器再次访问这个服务器的时候,会通过请求头将cookie传递给web服务器;
-
浏览器访问服务器的时候,只会携带由当前服务器存储在客户端的cookie;
-
Cookie中缓存的数据是以键值对的形式存储(name-value).
-
Cookie默认在浏览器关闭职工后,就立即失效,如果想长期有效,需要设置过期时间。
具体使用
后端更加关注如何发送Cookie和获取Cookie中的数据
发送Cookie
-
创建Cookie对象,并设置数据
Cookie cookie =new Cookie("key",value); -
发送Cookie到客户端:使用response对象
response.addCookie(cookie);
获取Cookie
-
获取客户端携带的所有Cookie,使用request对象
Cookie[] cookies=request.getCookies(); -
遍历数组,获取每一个Cookie对象:for
-
使用Cookie对象方法获取数据
cookie.getName(); cookie.getValue(); -
设置Cookie存活时间
semMaxAge(int seconds);参数值为:
- 正数:将Cookie写入浏览器所在电脑的硬盘,持久化存储。到时间自动删除
- 负数:默认值,Cookie在当前浏览器内存中,当浏览器关闭,则cookie被销毁
- 零:删除对应Cookie
具体演示:
首先我们先来创建一个ServletCookie,编写第一个Servlet发送Cookie
package com.qf.servlet.cookie;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/setCookie")
public class CookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建Cookie对象
Cookie cookie = new Cookie("name", "test");
//把cookie对象下发到浏览器中
response.addCookie(cookie);
//创建cookie对象
Cookie cookie2 = new Cookie("info", "time");
//如果当前的cookie2不设置保存时间,那么在浏览器关闭的同时失效。
//如果设置保存时间,cookie会保存到浏览器所在的电脑磁盘上,到达时间才会失效
cookie2.setMaxAge(60*60*24*30);//保存一个月
response.addCookie(cookie2);
}
}
getCookieServle获取cookie数据
@WebServlet("/getCookie")
public class getCookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取Cookie对象
//我们只能通过request对象获取所有的cookie数组
//获取客户端中的cookie
Cookie[] cookies = request.getCookies();
//非空判断
if(cookies != null) {
//遍历cookie,并且获取cookie中的所有数据
for(Cookie cookie : cookies) {
String name=cookie.getName();
String value= cookie.getValue();
System.out.println(name+":"+value);
}
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
先后使用浏览器访问setCookie和getCookie,可以看到控制台输出:
name : test
在浏览器按键F12查看cookie:也能看到name:test。此时cookie存储在浏览器中

cookie中文报错问题
有时候cookie会保存中文内容,但是可能会直接出现报错,因为cookie中一般时不能直接俄储存中文,需要进行转码。具体方式如下
- 在存入cookie的时候通过
URLEncoder.encode("张三","utf-8"),保证中文的存入 - 在取出的时候通过
URLDecoder.decode(string,string)来进行解码,就可以得到具体的中文值
//创建cookie对象
//URLEncoder.encode("张三","utf-8") 通过此方法在传递中文的时候用来编码
Cookie c1=new Cookie("username",URLEncoder.encode("张三","utf-8"));
response.addCookie(c1);
//获取Cookie对象
//我们只能通过request对象获取所有的cookie数组
//获取客户端中的cookie
Cookie[] cookies = request.getCookies();
//非空判断
if(cookies != null) {
//遍历cookie,并且获取cookie中的所有数据
for(Cookie cookie : cookies) {
String name=cookie.getName();
String value= cookie.getValue();
//如果保存的数据中有中文需要进行url解码
value=URLDecoder.decode(value,"utf-8")
System.out.println(name+":"+value);
}
Http Session
Session对象,就是当浏览器向服务器发送请求建立连接后,由服务器创建的存储在服务器端的用于记录用户状态对象。
特点
- 服务器会为每个客户端连接分配一个Session对象,存储在服务器上;
- 同一个浏览器发送多次请求,同属于一次会话,共享同一个session对象;
原理
Session原理:
- 当客户端浏览器(第一次)请求服务器时,服务器会为当前客户端连接创建一个新的session对象,同时将sessionID通过Cookie响应给客户端;
- 当客户端再次请求服务器的时候,会通过请求头携带存储sessionID的cookie,服务器接收请求后获取cookie中的sessionID ,通过这个sessionID获取第一次连接时创建的Session对象。
常用方法
HttpSession request.getSession();获取当前会话对象
void session.setAttribute([key],[vulue]);向会话中保存对象,键值对形式
Object session.getAttribute([key]);从会话中获取指定key的value值
void session.removeAttribute([key]);从会话中删除指定的key和它对应的value
String session.getId();获取当前会话的ID
void session.setMaxInactiveInterval([时间:秒]);设置HttpSession失效时间,单位秒(超市会断开连接,会话默认保持时间为30min)
void session.invalidate();设置当前的HttpSession立即失效
案例
Session的基本存取,证明在一次会话中多次请求使用的时同一个Session对象。
首先创建一个SessionServlet1用来存入Session数据
package com.qf.servlet.session;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/s1")
public class SessionServlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取session对象
HttpSession session = request.getSession();
System.out.println(session);
//存储数据
session.setAttribute("username","Tom");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
在创建一个SessionServlet2来取出session对象中的数据
package com.qf.servlet.session;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet("/s2")
public class SessionServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取session对象
HttpSession session = request.getSession();
System.out.println(session);
//取出session中的数据
String username=(String) session.getAttribute("username");
System.out.println(username);
}
}
运行项目,浏览器访问s1和s2,效果如图:

当前一个会话中,我们使用的是同一个session,地址完全相同,表示同一个session。
如何保证多次请求在一个会话中使用的都是一个Session对象?
Session是基于Cookie的
通过浏览器控制台查看,当浏览器请求以后,Session创建,并且咋响应的时候,会通过Cookie来存储当前这个Session的SessionID,通过这个ID就可以保证多次请求在一个会话中使用的都是一个Session对象。
访问http://localhost:8080/testweb_war/s1

访问http://localhost:8080/testweb_war/s2
浏览器就会通过请求头携带这个保存SessionID的Cookie发送到服务端,服务端拿到SessionID进行查找对应的session对象,这样就保证了使用同一个Session对象,完成一次会话多次请求的数据共享。

session失效
一个客户端的多次请求正常情况下获取到的是同一个session对象,如果session失效,将会导致失效后的请求无法获取之前的session对象。也就是说多次请求获取的不是同一个session对象。
导致session失效的原因有2种
- 客户端禁用Cookie,或客户端在两次请求之间清楚了cookie,将导致下一次请求无法获取上一次请求创建的cookie;
- session是有生命周期的,当哭护短请求服务器建立连接之后,服务器会为此会话创建session对象,如果客户端的两次请求时间间隔>session过期时间(默认30Min),服务器会将之前创建的session对象销毁。
session失效的解决方案
-
如果客户端禁用了Cookie:不能通过cookie来记录、传递sessionID,我们可以通过重写URL,使用URL传递sessionID(在url上追加sessionID)
-
如果session过期:我们可以根据系统的需求灵活设置session的生命周期或者手动销毁session对象
//设置session对象的过期时间(单位:s) //设置session过期时间10S,当客户端的两次请求时间>10s,session将会过期 session.setMaxInactiveInterval(10); //立即 手动销毁session对象(一般用于注销) session.invalidat();
2127

被折叠的 条评论
为什么被折叠?



