Skip to content

一 什么是会话

1 生活中会话

A:商量个事儿呗

B:嘛事

A:借点钱呗

B: 喂…喂…我这里信号不好…

2 Web中会话

打开浏览器-》访问应用-》关闭浏览器

用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。

每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,有时服务器要想办法为每个用户保存这些数据。

例如:在浏览器中保存用户的token

例如:用户通过超链接 访问一个购买功能的servlet 程序就需要急着购买的商品 以便于用户 在点结账的时候 结账功能的servlet 能够拿到购买的商品数据 为 用户结账

但是HTTP(超文本传输协议)是一个基于请求与响应模式的无状态协议。当同一个浏览器多次发送请求到服务器时,服务器并不知道是哪个浏览器发送的请求,即 HTTP 协议的请求无法保存用户状态。

Http无状态主要指 : 针对Http协议,服务器不能自动维护用户的上下文信息,无法保存用户状态; 每次请求都是独立的,不会受到前面请求的影响,也不会影响后面的请求。

由于 HTTP 协议是无状态的,无法保存和跟踪用户状态,所以需要其他的方案来解决问此题,它就是会话技术。常用的会话技术分为两种:

Cookie :浏览端会话技术 Session :服务端会话技术

3 会话技术

1)Cookie:将数据保存在浏览器客户端的技术

服务器把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了

2)Session:将数据保存在服务端的技术

服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务

Cookie

1 原理

image.png

1)服务端创建cookie对象

2)发送cookie信息到浏览器(HttpServletResponse 中提供void addCookie(Cookie cookie)方法)

例如,响应头中增加 Set-Cookie: name=zhangsan

3)浏览器将得到的cookie信息保存在浏览器端

4)通过浏览器下次访问web应用时,请求数据中会带上cookie信息例如,请求头中 Cookie: name=zhangsan

5)服务器端收到浏览器发送的cookie信息

2 使用

Cookie类中常用方法:

方法
Cookie(String name, String value)创建cookie对象的构造方法,value是字符串类型,tomcat8后value可以使用中文
String getName()取得Cookie的名字
String getValue()取得Cookie的值
void setValue(String newValue)设置Cookie的值
void setMaxAge(int expiry)设置Cookie的最大保存时间,单位秒,即cookie的有效期,默认会话结束,cookie失效。值为 0 时,表示删除该 Cookie
int getMaxAge()获取Cookies的有效期
void setPath(String uri)设置cookie的有效路径,比如把cookie的有效路径设置为"/aaa",那么浏览器访问"aaa"的web资源时,就会带上cookie
String getPath()获取cookie的有效路径

2.1 添加cookie

java
public void cookie1(HttpServletRequest request, HttpServletResponse response){
		//创建cookie对象
    Cookie cookie = new Cookie("name", "zhangsan");

    //如果有相同name值得cookie,后一个会替换前一个cookie内容
    //Cookie cookie1 = new Cookie("name", "lisi");

    //cookie中的name和value都是字符串类型
    //Cookie cookie1 = new Cookie("age", "10");

    //tomcat8之后,cookie中支持中文
    //Cookie cookie1 = new Cookie("name", "张三");

    //通过响应将cookie数据发送到浏览器端
    response.addCookie(cookie);
    //response.addCookie(cookie1);

}

注意:在tomcat 8 之后,cookie支持中文数据,但是某些特殊字符还是不支持,比如空格、分号等,需要借助URLEncoder.encode(字符串, "utf-8")进行编码。 这种特殊字符也不用刻意去记,出问题后,直接进行编码

2.2 遍历cookie

java
public void cookie1(HttpServletRequest request, HttpServletResponse response){

    //获取请求中的cookie数据
    Cookie[] cookies = request.getCookies();
    if(cookies != null){
        for (Cookie cookie2 : cookies) {
            // 获取cookie的name和对应的value
            System.out.println(cookie2.getName());
            System.out.println(cookie2.getValue());
        }
    }
}

2.3 设置cookie的过期时间

java

public void cookieTime(HttpServletRequest request, HttpServletResponse response){

    Cookie cookie = new Cookie("name", "zhangsan");
    //设置cookie的过期时间
    //单位秒
    //		cookie.setMaxAge(60 * 60);

    //可以实现删除已有的cookie
    //		cookie.setMaxAge(0);

    //过期时间:会话结束时
    cookie.setMaxAge(-1);

    response.addCookie(cookie);

}

练习:

页面上显示上一次访问时间,访问时间要求通过cookie存储

3 特点

一个cookie不能超过4k;

一个浏览器最多存300个cookie;

一个站点最多存20个cookie

Session

在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),可用用于保存客户端用户的访问状态。

注意: 一个浏览器独占一个session对象 同一浏览器的不同窗口共享同一 Session 对象,但不同浏览器窗口之间不能共享 Session 对象。 Session依赖于cookie 不同的Servlet可以共享同一Session对象中的数据

1 原理

image.png

1)访问应用时,如果创建session(request.getSession()),每个session对象会分配一个id,称谓JSESSIONID

2)服务器会将session的id以cookie的形式发送给浏览器端,浏览器端会存储该id

3)以后再访问应用时,浏览器将session的id发送给服务端

4)服务端收到session的id后,会根据id查找对应的session对象,如果没有找到,创建一个新的session对象

2 使用

HttpSession中常用方法:

方法
String getId( )获取当前的会话ID。每个会话在服务器端都存在一个唯一的标示sessionID,session对象发送到浏览器的唯一数据就是sessionID,它一般存储在cookie中。
void setMaxInactiveInterval(int interval)指定在无任何操作的情况下,设置会话的最大持续时间,单位是秒,默认30分钟,负数表明会话永不失效
int getMaxInActiveInterval()获取会话的最大持续时间
void setAttribute(String name,String value)设定指定名字的属性的值,并将它添加到session会话范围内
Object getAttribute(String name)在会话范围内获取指定名字的属性的值,返回值类型为object,如果该属性不存在,则返回null
void removeAttribute(String name)删除指定名字的session属性
void invalidate()使session失效。可以立即使当前会话失效,原来会话中存储的所有对象都不能再被访问
long getLastAccessedTime()返回上一次发送与此 Session 关联的请求的时间

2.1 创建session对象

java
//会根据session的id 查找服务端是否有对应的session对象,如果有,返回session对象;如果没有创建session对象
//创建session对象后,会将JSESSIONID以cookie的形式存在浏览器端
HttpSession session = request.getSession();

//根据JSESSIONID找session对象,如果存在,返回;如果不存在,返回null
// HttpSession session = request.getSession(false);

//session的id,唯一的   JSESSIONID
String id = session.getId();
System.out.println(id);

//默认情况下,JSESSIONID的过期时间是会话结束时,为了能正常访问session对象,需要手动将JSESSIONID存储到cookie中,并设置一个合适的过期时间
Cookie cookie = new Cookie("JSESSIONID", id);
cookie.setMaxAge(30 * 60);
response.addCookie(cookie);

//设置session的过期时间,单位秒,默认30分钟
session.setMaxInactiveInterval(10 * 60);

//向session域中存入数据
session.setAttribute("name", "张三");

2.2 不同的servlet间共享session对象中数据

java
// 在一个servlet中存储数据
session.setAttribute("name", "zhangsan");

// 在另一个servlet中读取数据
System.out.println(session.getAttribute("name"));

2.3 web.xml中设置session的超时时间

单位分钟

java
<session-config>
  <session-timeout>10</session-timeout>
</session-config>

练习:

访问一个资源时,如果没有登录过,跳转到登录界面。如果登录过,在一定时间内,可以直接访问该资源

3 禁用cookie的处理 了解

session依赖cookie,因为服务器需要根据sessionId,然后找到客户端的session对象,如果浏览器禁用了cookie,就需要对URL进行重写,这样服务器收到的请求中就会带有sessionId。

使用方法:response.encodeURL(String url)

它会判断客户端浏览器是否禁用了Cookie,如果禁用了,那么这个方法会在URL后面追加jsessionid,否则不会追加。

java
Session session = req.getSession();
// /day36_session/main;jsessionid=8BE9D12D48CB4C51532A9C007698EEFF
String encodeURL = response.encodeURL(request.getContextPath() + "/main");
response.sendRedirect(encodeURL);

注意 要使用到session 上述代码才能生效 , 原理是 把sessionId 拼到每次请求的后面 实现 sessionId 的跟踪,他会检查你的客户端cookie 有没有带sessionId 如果 没有 则把sessionId 写到 请求路径后面 以参数的形式 进行传递

4 Cookie与Session的不同

CookieSession
Cookie 将数据存放在浏览器端Session 将数据存储在服务器端
浏览器对 Cookie 的大小和数量有限制Session 的大小和数量一般不受限制
Cookie 中保存的是字符串Session 中可以保存任意类型的对象
Cookie 明文传递,安全性低Session 存在服务器端,安全性较高
Cookie 保存在客户端,不占用服务器资源Session 保存在服务端,若并发访问的用户十分多,就会占用大量服务端资源

5 request/session/ServletContext

request、session 和ServletContext 称为 Servlet 的三大域对象,它们都能实现资源间共享数据

requestsessionServletContext
只对当前请求涉及的 Servlet 有效,通过请求的转发可以实现一次请求中资源之间共享数据。session 对本次会话期间的所有 Servlet 都有效,session对象过期,手动调用方法销毁,会话结束对整个 Web 应用内的所有 Servlet 有效