session

目录

1. javaweb中的Session

2. Session实现的底层原理:

3. 浏览器禁用Cookie会出现的问题

4. 浏览器关闭, 服务器端对应的Session对象会销毁吗

5. Session对象在什么时候销毁

6. 到底什么是一次会话?

7. HttpSession相关的常用方法

8. HttpSession和HttpServletRequest接口的对比


1. javaweb中的Session

    1. Session表示会话, 不止在javaweb中存在, 只要是web开发, 都会有这种会话机制

    2. 在java中会话对应的类型为: java.servlet.http.HttpSession, 简称session/会话

    3. Cookie可以将会话状态保存在客户端, 而HttpSession可以将会话状态保存在服务器端

    4. HttpSession对象是一个会话级别的对象, 一次会话对应一个HttpSession对象

    5. 什么是一次会话?

       目前可以这样理解, 用户打开浏览器, 访问web服务器, 在浏览器上发送多次请求
       直到最后关闭浏览器(停止访问web服务器), 表示一次完整的会话.
       所以一次会话包括多次请求.
       例子如下:

       public class HttpSessionServlet extends HttpServlet {

        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 获取ip
        String ip = request.getRemoteAddr();
        // 获取会话状态
        HttpSession session = request.getSession();
        // 不同的用户访问会有不同的Session
        // 如果用户不变, 连续访问, Session也不变
        System.out.println(ip + "的Session为" + session);
        }
    }

    直接访问多次:始终打印: 0:0:0:0:0:0:0:1的Session为org.apache.catalina.session.StandardSessionFacade@71d180de
    关闭浏览器后再次访问: 0:0:0:0:0:0:0:1的Session为org.apache.catalina.session.StandardSessionFacade@1fff9fca
    两次并不一样, 这是因为两次不是一个会话


    6. web服务器一直为当前用户维护着一个会话对象, 就是HttpSession对象

    7. 在web容器中, 一直维护了大量的HttpSession对象, 换句话说, Web容器中应该存在一个session列表(Map结构)

       思考: 为什么当前会话中的每一次请求可以获取到属于自己的会话对象?

       举个生活中的例子: 上体育课, 我打篮球, 这个篮球手感不错, 我想下一节课继续用这个篮球, 我给这个篮球上
       做一个标记, 然后再脑子中记住这个标记, 下节课我来的时候就找这个标记标的篮球
       这里篮球就是一个Session对象, 篮球上的标记是这个Session对象对应的Cookie, 在服务器中, 
       脑中的记忆就像是客户端的Cookie, 如果我脑中忘记这个标记就代表我找不到这个篮球了
       这对应浏览器清理缓存时候将Cookie清除, 所以关闭浏览器访问的Session是不同的

2. Session实现的底层原理:

    原理如下:
        打开浏览器, 在浏览器上发送首次请求
        服务器会创建一个HttpSession对象, 该对象代表一次会话
        同时生成HttpSession对象对应的Cookie对象, 并且Cookie对象的name是JSESSIONID, Cookie的value是32位长度的字符串
        服务器将Cookie的value和Session对象绑定到Session列表中
        服务器将Cookie完整的发送给浏览器客户端
        浏览器将Cookie保存到缓存中, 只要浏览器不关闭, 或者不删除Cookie信息, Cookie不会消失
        当再次发送请求时, 会自动提交缓存中的Cookie
        服务器接收到Cookie, 验证该Cookie的name确实是JSESSIONID, 然后获取Cookie中的value
        通过Cookie的value在Session列表中找对应的对象

    抓个包看看情况:
    第一次访问资源的时候, 在响应对象中生成了如下的Cookie信息
    第一次响应对象生成的Cookie: JSESSIONID=22494267CE4228BD051AF151C5C71200;
    此时标准输出打印如下(代码还是上面的代码): 0:0:0:0:0:0:0:1的Session为org.apache.catalina.session.StandardSessionFacade@677aed17
    不关闭浏览器刷新, 在新的包中请求对象中发送了如下Cookie信息
    不关浏览器刷新发送的Cookie: JSESSIONID=22494267CE4228BD051AF151C5C71200
    这两条Cookie一模一样
    此时标准输出打印如下(代码还是上面的代码): 0:0:0:0:0:0:0:1的Session为org.apache.catalina.session.StandardSessionFacade@677aed17
    现在关闭浏览器(代表清理缓存), 或者清除当前页面的Cookie
    在响应对象中又生成了新的Cookie
    响应对象生成的新Cookie信息如下Cookie: JSESSIONID=AB5FED2711F6427A92709C4EB8ED3A62;
    和之前的Cookie信息不一样,
    此时标准输出打印如下(代码还是上面的代码): 0:0:0:0:0:0:0:1的Session为org.apache.catalina.session.StandardSessionFacade@3598841e
    说明Session对象也不一样了

3. 浏览器禁用Cookie会出现的问题

    浏览器禁用Cookie则浏览器的缓存中不在保存Cookie
    导致在同一次会话中, 无法获取到对应的会话对象
    禁用Cookie之后, 每一次获取的会话对象都是新的

    浏览器禁用Cookie之后, 如果还想拿到对应的Session对象, 必须使用URL重写机制
        将上一次的Cookie记录下来, 在URL栏的后面加上";jsessionid=xxxxxx"(xxxxx是上一次的JSESSIONID复制过来的)

4. 浏览器关闭, 服务器端对应的Session对象会销毁吗

    不会销毁, 因为B/S架构的系统Http协议, 而http协议是一种无连接无状态的协议, 服务器根本不知道你浏览器关闭了(会话结束了).

    什么是无连接/无状态?
        典型的例子是, 断网之后加载好的网页依旧可以显示, 服务器不知道浏览器端已经断开连接了
        请求的瞬间浏览器和服务器之间的通道是打开的, 请求响应结束之后, 通道关闭
        这样做的目的是降低服务器的压力

5. Session对象在什么时候销毁

    web系统中引入了Session超时的概念, 当很长一段时间(这个时间可以给定)
    没有用户访问该session对象, 此时session对象超时, web服务器会自动回收Session对象
    可以在web.xml文件中配置
    加入下面语句

        <session-config>
        <session-timeout>120</session-timeout>
        </session-config>

    这个代表120分钟内, 没有用户访问这个Session对象, 会被web服务器回收
    不配置时候, 默认是30分钟
    经常出现这种现象, 在某个页面上很久为操作, 再次操作时会显示让你重新登录

6. 到底什么是一次会话?

    本质上, 会话是指一个终端用户与交互系统进行持续通讯的一次过程, http协议是一种无连接无状态的协议, 其中通过Session和Cookie机制确保一次会话的状态

    http中Session对象被创建到Session对象被销毁叫为一次会话的全过程
    但是大部分情况下, 用户打开浏览器, 在浏览器上进行操作, 然后将浏览器关闭, 通常代表一次会话结束.

7. HttpSession相关的常用方法

    创建或者获取Session, 通过request对象创建

    request.getSession()/request.getSession(true)  // 这两个方法一样, 获取Session对象, 如果没有Session对象则新建对象
    request.getSession(false)  // 获取Session对象, 如果没有Session对象则返回null

    HttpSession是一个接口

    void setAttribute(String name, Object value)  // 存某一条信息
    Object getAttribute(String name)  // 取某一条信息

    关于这两个放, 给出例子:
    这个Servlet是向会话对象中存入数据

    public class SetSessionServlet extends HttpServlet {

        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 从请求对象中获取Session
        HttpSession session = request.getSession();
        // 向Session存入数据
        session.setAttribute("username", "zhangsan");

        }
    }

    下面这个Servlet是从会话对象中取出数据

    public class GetSessionServlet extends HttpServlet {

        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 从请求对象中获取Session
        HttpSession session = request.getSession();
        // 从Session中获取数据
        Object username = session.getAttribute("username");
        // 打印数据
        System.out.println(username);
        }
    }

    先访问"/setSession", 再访问"/getSession"打印结果如下
    zhangsan
    这说明, 一次一次会话可以包括多次请求

    void removeAttribute(String name)  // 删某一条信息
    void invalidate()  // 销毁整个Session

    可以通过invalidate()实现安全退出
    下面的代码就是销毁Session对象, 实现安全退出
 

    public class DestroySessionServlet extends HttpServlet {

        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // 获取Session对象, 如果没有Session对象则返回null
            HttpSession session = request.getSession(false);
            if (session != null) {
                // 销毁Session对象
                session.invalidate();
            }
        }
    }

8. HttpSession和HttpServletRequest接口的对比

    1. 上面两个都是范围对象

        HttpSession session; 是会话范围
        HttpServletRequest request; 是请求范围

    2. 两个范围的大小

        session > request

    3. 功能 

        session完成的是跨请求共享, 但是这些请求必须在同一个会话
        request完成跨Servlet共享数据, 但是这些Servlet必须在同一个请求中(转发)

    4. 使用原则

        由小到大尝试, 优先使用小范围
        例如: 登录成功之后, 已经登录的状态需要保存起来, 可以将登录成功的状态保存在session对象中
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值