目 录CONTENT

文章目录

Session

在等晚風吹
2023-12-05 / 0 评论 / 0 点赞 / 10 阅读 / 0 字 / 正在检测是否收录...

HttpSession对象

Session是什么

​ session和cookie就是为解决HTTP协议的无状态采用的两种解决方案,称为会话跟踪技术。与cookie将信息保存在客户端不同,session将信息保存在服务器端解决。

​ PS : 一次请求,指的是客户端发送数据到服务器端,服务器端接收并相应,这可以称之为一次请求。由于HTTP协议是无状态的,你无法从一个请求中拿到另一个请求中的数据,多个请求之间的数据无法共享,那么就引入会话的概念。会话怎么理解呢?就好比你和我坐下来聊天谈话,你问我答,你问我答,你再问我前面的问题我还是可以回答你,整个会话聊天中的内容我们可以随时交谈使用。那我们这里说的会话(Session)指的是什么:

​ 对于服务器而言,每一个连接到它的客户端,都产生一个会话 (Session),服务端为他们之间的会话创建一个session对象。servlet 容器使用 javax.servlet.http.HttpSession接口创建 HTTP 客户端和 HTTP 服务器之间的会话(构建HttpSession对象- Session在服务器端对应的实现是:HttpSession对象是 javax.servlet.http.HttpSession 的实例。)。Session是在服务器端生成的,存储在服务器端,即存在内存中。

​ Session生成的同时,会生成一个与之相关联的的SessionID, 此SessionID的存储是需要Cookie来完成的。SessionID是以名称为JSESSIONID、其值应该是一个既不会重复,又不容易被找到规律以仿造的字符串组成。SessionID会随着此次Http 响应,一并返回到客户端,并保存在客户端中。到当前请求再次发出后,该SessionID会随着Http头部,传到服务器中,服务器依据当前SessionID 得到与之对应的session。

​ 一次会话(一个用户的多次请求)期间共享数据。我们可以通过 request.getSession()方法,来获取当前会话的 session 对象。

// 如果session对象存在,则获取;如果session对象不存在,则创建
HttpSession session = request.getSession();

案例:

在Servlet中获取Session内容:

package com.msb.testsession;

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;

/**
 * @Author: zhaoss
 */
@WebServlet("/testsession01")
public class TestSession01 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取Session对象:
        HttpSession session = req.getSession();
        // 获取Session的唯一标识符:
        String id = session.getId();
        System.out.println(id);
        // 断判是否是新的session对象:
        System.out.println(session.isNew());
    }
}

你也可以请求其它页面,只要在同一个会话中,JSESSIONID都有效。(客户端请求服务器,会话即开启)

结论:

第一次访问发送请求到后端,第一次没有创建会话(Session)之前,那么由服务器创建一个HttpSession,并且将HttpSession对应的Sessionid绑定到http协议中响应回客户端。

第二次再访问,请求的时候在http请求协议中会在Cookie中携带Sessionid ,那么后台就会根据这个id取出对应的HttpSession。

测试,关闭服务器再重新测试,观察Sessionid的变化。

测试,关闭浏览器再重新测试,观察Sessionid的变化。

发现:一次会话(浏览器打开到关闭,访问多页页面,都在一个会话中)结束,结束后再次访问时,那么会创建新的Session。

标识符 JSESSIONID

​ Session 既然是为了标识一次会话,那么此次会话就应该有一个唯一的标志,这个标志就是 sessionId。

​ 每当一次请求到达服务器,开启了会话,服务器第一步会查看是否从客户端回传一个名为 JSESSIONID 的 cookie,如果没有则认为这是一次新的会话,会创建 一个新的 session 对象,并用唯一的 sessionId 为此次会话做一个标志。如果有 JESSIONID 这 个cookie回传,服务器则会根据 JSESSIONID 这个值去查看是否含有id为JSESSION值的session 对象,认为是之前标志过的一次会话,返回该 session 对象,数据达到共享。

​ 服务器在创建好Session对象后,服务器会将Session对象的id以Cookie的形式保存在客户端(浏览器),用户在发请求的时候,就会带上该Cookie,也就是SessionId到服务器,服务器会根据该id找到用户的Session对象。存储SessionId的Cookie不需要我们自己创建,我们在调用服务器完成Session创建的时候,Tomcat服务器会自动的创建Cookie,Cookie里面保存的是SessionId并响应给浏览器。但是注意,Cookie默认的有效期为浏览器运行期间,浏览器关闭,Cookie即失效。

​ 不管是存储了用户SessionId的Cookie信息丢失,还是服务器存储的Session对象被销毁,(无论你是关闭浏览器还是关闭服务器,相当于会话断开了)默认只要服务器接收到用户发起的请求后,如果找不到对应的Session对象,都会重新创建,并将新的SessionId以Cookie的形式保存到浏览器中 。

session的使用

​ Session 用来表示一次会话,在一次会话中数据是可以共享的,这时 session 作为域对象存在(会话是一个域,在其中共享数据),可以通过setAttribute(name,value) 方法向域对象中添加数据,通过 getAttribute(name) 从域对象中获取数据,通过 removeAttribute(name) 从域对象中移除数据。

​ 数据存储在 session 域对象中,当 session 对象不存在了,数据也就不能共享了。这就不得不谈到 session 的生命周期。

案例:

​ 请求Servlet,将数据存于Session中(存两个,删一个),然后请求转发到另一个Servlet,从另一个Servlet中取出Session:

package com.msb.testsession;

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("/ts02")
public class TestSession02 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取Session对象:
        HttpSession session = req.getSession();
        // 在session域对象中存入内容:
        session.setAttribute("uname1","lili");
        session.setAttribute("uname2","feifei");

        // 移除指定名称的session域对象:
        session.removeAttribute("uname2");

        // 请求转发到另一个Servlet:
        req.getRequestDispatcher("/ts03").forward(req, resp);

    }
}
package com.msb.testsession;

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("/ts03")
public class TestSession03 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取Session对象:
        HttpSession session = req.getSession();
        // 获取指定名称的session域对象:
        String uname = (String)session.getAttribute("uname1");
        System.out.println(uname);
        String uname2 = (String)session.getAttribute("uname2");
        System.out.println(uname2);


    }
}

控制台结果:

lili
null

session对象的销毁

默认时间到期

​ 可以对生成的 Session 设置过期时间,如果不设置过期时间,默认的Session过期时间是30分钟(在不同的服务器中,它的过期时间略有不同,以Tomcat为案例来说)。

​ 那么 session 的默认时间可以改么?答案是肯定的。可以在 Tomcat 中的 conf 目录下的 web.xml 文件中进行修改。

<!-- session 默认的最大不活动时间。单位:分钟。 -->
<session-config>
	<session-timeout>30</session-timeout>
</session-config>

​ 当客户端第一次请求 servlet 并且操作 session 时,session 对象生成,Tomcat 中 session 默认的存活时间为 30min**(指的是这30min完全不操作),即你不操作界面的时间,一旦有操作,session 会重新计时。**

​ 当然我们也可以通过 getMaxInactiveInterval() 方法来查看当前 Session 对象的最大不活动时间。

// 获取session的最大不活动时间
int time = session.getMaxInactiveInterval();

​ 实际案例:在登录某个网站的时候,比如长时间不用以后,登录信息就过期了,你再操作就让你重新登录了,那就是因为登录数据都存在session中了,超过有效时间,session就消失了,那么就需要重新登录。

自己设定到期时间

​ 当然除了以上的修改方式外,我们也可以在程序中自己设定 session 的生命周期,通过session.setMaxInactiveInterval(int) 来设定 session 的最大不活动时间,单位为秒。

// 获取session对象 
HttpSession session = request.getSession();
// 设置session的最大不活动时间
session.setMaxInactiveInterval(15); // 15秒

立刻失效

​ 或者我们也可以通过 session.invalidate() 方法让 session 立刻失效

// 销毁session对象
session.invalidate();

​ 代码:

package com.msb.testsession;

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("/ts04")
public class TestSession04 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 获取session对象:
        HttpSession session = req.getSession();
        // 立即失效:
        session.invalidate();
        // 设置session的最大不活动时间:
        //session.setMaxInactiveInterval(30);
        // 获取session的最大不活动时间:
        /*int time = session.getMaxInactiveInterval();
        System.out.println(time);*/
    }
}

关闭浏览器

​ 从前面的 JESSIONID 可知道,session 依赖 cookie 实现,并且该 cookie 的有效时间为关闭浏览器,从而 session 在浏览器关闭时也相当于失效了(因为没有 JSESSION 再与之对应)。

关闭服务器

​ 当关闭服务器时,session 销毁。

​ Session 失效则意味着此次会话结束,数据共享结束。

0

评论区