深度好文之Servlet技术详解(八)HttpSession对象

深度好文之Servlet技术详解(八)HttpSession对象,第1张

目录

一.HttpSession对象的特点

二.HttpSession对象的创建

三.HttpSession对象的使用

四.HttpSession的销毁方式

五.通过HttpSession实现客户端与服务端会话的维持

六.HttpSession生命周期

七.HttpSession对象总结

1.HttpSession与Cookie的区别

2.HttpSession的使用建议


一.HttpSession对象的特点
  • HttpSession保存在服务端
  • HttpSession使用KeyValue结构存储数据
  • HttpSessionKey是字符串类型,Value则是Object类型
  • HttpSession存储数据大小无限制,Cookie存储数据大小有限制
二.HttpSession对象的创建

HttpSession 对象的创建是通过 request.getSession() 方法来创建的。客户端浏览器在请求服务端资源时,如果在请求中没有 jsessionid getSession() 方法将会为这个客户端浏览器创建一个新 HttpSession 对象,并为这个 HttpSession 对象生成一个 jsessionid ,在响应中通过 状态Cookie 写回给客户端浏览器,如果 在请求中包含了 jsessionid getSession() 方法则根据这个 ID 返回与 这个客户端浏览器对应的 HttpSession 对象。 getSession() 方法还有一个重载方法 getSession(true|false) 。当参数为 true 时与 getSession() 方法作用相同。当参数为 false 时则只去 根据 jsessionid (无需指定)查找是否有与这个客户端浏览器对应的 HttpSession ,如果有则返回,如果没有 jsessionid 则不会创建新的 HttpSession 对象。

每个浏览器都有自己的session对象。

CreateHttpSessionServlet.java:

package com.first.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

public class CreateHttpSessionServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建HttpSession对象
        //true可不传,若传false,则没有session对象则不创建对象,即session是null,若有则返回
        HttpSession session= req.getSession(true);
        System.out.println(session);

        PrintWriter pw=resp.getWriter();
        pw.println("Create HttpSession ok!");
        pw.flush();
        pw.close();
    }
}

web.xml配置:

    
        CreateHttpSessionServlet
        com.first.servlet.CreateHttpSessionServlet
    
    
        CreateHttpSessionServlet
        /session.do
    

输出:

换个浏览器试试,发现 jsessionid不一样了,我这里就不演示了。 

 控股台输出:

org.apache.catalina.session.StandardSessionFacade@6d46c82c

三.HttpSession对象的使用 session.setAttribute("key",value) 将数据存储到 HttpSession 对象中 Object value = session.getAttribute("key") 根据 key 获取 HttpSession 中的数据,返回 Object Enumeration attributeNames = session.getAttributeNames() 获取 HttpSession 中所有的 key ,返回枚举类型 session.removeAttribute("key") 根据 key 删除 HttpSession 中的数据 String id = session.getId() 根据获取当前 HttpSession SessionID ,返回字符串类型 在CreateHttpSessionServlet.java中增添如下代码:
        //存放数据
        session.setAttribute("key1","下一次");
        //获取sessionID
        String sessionID=session.getId();
        System.out.println("sessionID: "+sessionID);
GetHttpSessionDataServlet.java:
package com.first.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

public class GetHttpSessionDataServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取HttpSession对象
        HttpSession session=req.getSession();
        //获取数据
        String value= (String) session.getAttribute("key1");

        PrintWriter pw=resp.getWriter();
        pw.println(value);
        pw.flush();
        pw.close();
    }
}

配置web.xml:

    
        GetHttpSessionDataServlet
        com.first.servlet.GetHttpSessionDataServlet
    
    
        GetHttpSessionDataServlet
        /getSession.do
    

输出:

控制台输出:

session: org.apache.catalina.session.StandardSessionFacade@5fffb2bc
sessionID: 8E5DA726F902D8CA52F74045795C28A9

浏览器输出:

 注意一个浏览器对应一个session,关闭浏览器再打开登陆localhost:8888/ajaxDemo/session.do,会发现jsessionid变了,因为一关闭浏览器状态Cookie会被销毁,所以又创建了新的session对象,原来的session对象不会立即销毁,而是放到了HttpSession对象列表里。

四.HttpSession的销毁方式 HttpSession 的销毁方式有两种:
  • 通过web.xml文件指定超时时间
  • 通过HttpSession对象中的invalidate()方法销毁当前HttpSession对象
我们可以在 web.xml 文件中指定 HttpSession 的超时时间,当到达指定的超时时间后,容器就会销该 HttpSession 对象,单位为分钟。 该时间对整个 web 项目中的所有 HttpSession 对象有效。时间的计算 方式是根据最后一次请求时间作为起始时间。只要用户继续访问, 服务器就会更新 HttpSessio 的最后访问时间,并维护该 HttpSession 。用户每访问服务器一次,无论是否读写 HttpSession ,服务器都认为该用户的 HttpSession" 活跃 active " 了一次 , 销毁时间则会重新计算。如果有哪个客户端浏览 器对应的 HttpSession 的失效时间已到,那么与该客户端浏览器对应 HttpSession 对象就会被销毁。其他客户端浏览器对应的 HttpSession 对象会继续保存不会被销毁。

示例思路,在第二节CreateHttpSessionServlet.java基础上修改,用两个浏览器访问这个servlet,一个浏览器的HttpSession到达指定的超时时间后销毁,但另一个时不时刷新一下(为的是重新计时),所以没有销毁,以此验证上面那段话。

如何区分浏览器,看请求头中的User-Agent。

配置web.xml:

这个没有位置要求

    
        
        1
    
CreateHttpSessionServlet.java:
package com.first.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

public class CreateHttpSessionServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求头中的User-Agent的数据
        String header=req.getHeader("User-Agent");

        //创建HttpSession对象
        //true可不传,若传false,则没有session对象则不创建对象,即session是null,若有则返回
        HttpSession session= req.getSession(true);
        System.out.println("session: "+session);

        //看着是key是一样的,但其实两个浏览器的HttpSession是不一样的
        if (header.indexOf("Chrome")!=-1){
            session.setAttribute("browser","Chrome");
            //销毁session对象
            //session.invalidate();
        }else {
            session.setAttribute("browser","Firefox");
        }

        //存放数据
        session.setAttribute("key1","下一次");
        //获取sessionID
        String sessionID=session.getId();
        System.out.println("sessionID: "+sessionID);

        PrintWriter pw=resp.getWriter();
        pw.println("Create HttpSession ok!");
        pw.flush();
        pw.close();
    }
}
GetHttpSessionDataServlet.java:
package com.first.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

public class GetHttpSessionDataServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取HttpSession对象
        HttpSession session=req.getSession();
        //获取数据
        String value= (String) session.getAttribute("browser");
        resp.setContentType("text/plain;charset=utf-8");
        PrintWriter pw=resp.getWriter();
        pw.println(value);
        pw.flush();
        pw.close();
    }
}

 输出:

没超时之前

超时之后

而火狐期间时不时刷新一下,重新计时,HttpSession对象就一直没被销毁。


我们也可以在 Tomcat web.xml 文件(在Tomcat安装目录的conf文件中,而不是项目的web.xml,如果下面的配置代码写到项目的web.xml中,那么启动Tomcat时会报错)中配置 HttpSession 的销毁时间。如果在 Tomcat web.xml 文件中配置了 HttpSession 的超时时 间对应的是 Tomcat 中所有的 Web 项目都有效。相当于配置了全局的 HttpSession 超时时间。如果我们在 Web 项目中配置了超时时间, 那么会以 Web 项目中的超时时间为准。 在这里配置的超时时间是全局的,即在Tomcat中部署的所有项目都受此超时时间设定(项目没有根据上面那个方式单独给自己部署的情况下) invalidate() 方法是 HttpSession 对象中所提供的用于销毁当前HttpSession 的方法。我们通过调用该方法可以销毁当前 HttpSession 对象。
session.invalidate();
五.通过HttpSession实现客户端与服务端会话的维持 需求:当客户端浏览器第一次访问 Servlet 时响应 您好,欢迎您第一次访问! ,第二次访问时响应 欢迎您回来!
package com.first.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;

public class WelcomeSessionServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取HttpSession对象
        //false参数:没有session对象也不会创建新的
        HttpSession session=req.getSession(false);
        boolean flag=true;
        //如果是第一次访问那么肯定不存在session对象
        if (session==null){
            flag=false;
            //创建session对象
            req.getSession();
        }

        resp.setContentType("text/plain;charset=utf-8");
        PrintWriter pw=resp.getWriter();
        if (flag){
            pw.println("欢迎您回来!");
        }else {
            pw.println("您好,欢迎您第一次访问!");
        }
    }
}

配置web.xml:

    
        WelcomeSessionServlet
        com.first.servlet.WelcomeSessionServlet
    
    
        WelcomeSessionServlet
        /welcomeSession.do
    

输出:

 刷新:

刚开始Tomcat是默认自己打开Chrome浏览器的,默认执行index.js

index.js里面有创建session对象的代码,所以刚开始开发者工具里面会有一条jsessionid。

六.HttpSession生命周期 HttpSession 对象生命周期中没有固定的创建时间与销毁时间。何时创建取决于我们什么时候第一次调用了 getSession() getSession(true) 的方法。 HttpSession 对象的销毁时间取决于超时 时间的到达以及调用了 invalidate() 方法。如果没有超时或者没有调 invalidate() 方法,那么 HttpSession 会一直存储。默认超时时间 30 分钟 (Tomcat web.xml 文件配置的时间就是默认超时时间 ) 七.HttpSession对象总结 1.HttpSessionCookie的区别
  • cookie数据存放在客户的浏览器或系统的文件中,而HttpSession中的数据存放在服务器中。
  • cookie不安全(因为明文存储),而HttSession是安全的。
  • 单个cookie保存的数据不能超过4K,很多浏览器都限制一个域名保存cookie的数量。而 HttpSession没有容量以及数量的限制。
2.HttpSession的使用建议 HttpSession 对象是保存在服务端的,所以安全性较高。我们可以在HttpSession 对象中存储数据,但是由于 HttpSession 对象的生命周 期不固定,所以不建议存放业务数据。一般情况下我们只是存放用 户登录信息。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/798371.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-06
下一篇 2022-05-06

发表评论

登录后才能评论

评论列表(0条)

保存