Session

Session是服务器为每个访问这个服务器的客户端用户创建的一个容器。这个容器中存储的数据能够在多个request之间实现共享。而且,这个容器只属于当前这个用户。
Session是怎么标识每一个用户的
表面上,我们说Session容器是属于某一个用户。其实在会话过程中,只有客户端(浏览器)和服务器两个角色。所以,Session容器标识的不是用户,而是当前用户正在使用的浏览器。浏览器与服务器交流是通过给服务器发送请求实现的,浏览器的每次请求中如果都有一个相同的标记用来标记session。服务器就能够识别这个用户了。

这个标记叫做JSESSIONID。我们重新演示,cookie的setPath练习,发现服务器启动后,浏览器的每次请求都会携带一个name属性值为"JSESSIONID"的cookie,这个cookie的值在每次请求过程中都是相同的。

Session的作用
为每个访问服务器的用户创建一个存储数据的容器;
容器中的数据在多个请求之间共享;

获得Session对象API
Session容器的创建,调用的方法是:request.getSession()。

//获取Session容器对象(创建session对象)
   HttpSession session = request.getSession();
   System.out.println(session);

session常用API
Session实践:
需求:

  1. 在第一个Servlet中往Servlet中存储数据;
  2. 在另外两个Servlet中获取session和session中存储的值,分别打印session和值;
//往session中设置值
@WebServlet("/sessionone")
public class SessionOneServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //在session中存储值
        //获取session
        HttpSession session = request.getSession();
        //储存值
        session.setAttribute("session","sessionvlaue");
    }
}
//从session中取值
@WebServlet("/sessontwo")
public class SessionTwoServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取session中存储的值
        //获取session
        HttpSession session = request.getSession();
        String session1 = (String) session.getAttribute("session");
        System.out.println("session1 = " + session1);
    }
}

Session的生命周期
当客户端浏览器第一次访问服务器时,服务器默认为每个浏览器创建不同的HttpSession对象。我们可以使用request.getSession()方法来获得HttpSession对象。

当第一次执行 request.getSession()时,有session对象就返回创建的session,没有session就创建session对象。后续的request.getSession()只能获取已创建的session。

Session销毁
方式一:时间超出了session的存活时间
session的默认存活时间是30分钟,在tomcat的全局配置文件web.xml中。(路径:tomcat/config/web.xml)
我们可以在web.xml中自己设置这个存活时间。我们设置的这个时间会覆盖原来的存活时间。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
		  http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"
           version="3.1">
    <!--将session的存活时间设置成1-->
    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>
</web-app>
//获取session
        HttpSession session = request.getSession();
        //打印session和sessionId
        System.out.println("session="+session+";sessionId="+session.getId());

注意: Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session"活跃(active)"了一次。

方式二:在Servlet中手动销毁
手动销毁session,调用的方法是:session.invalidate()方法;

 //可以删除session
        HttpSession session = request.getSession();//可以获取session
        System.out.println(session.getId());

        session.invalidate();//session被销毁了

浏览器关闭后,session持久化方案
通过上面的例子我们发现,浏览器关闭后,JSESSIONID就消失了,再次访问的时候又重新创建了一个新的session对象。这样,是比较消耗资源的。
session之所以重新创建是因为,浏览器关闭后JESSIONID这个cookie消失了。所以,就不能够在标识这个session了。如果能够让cookie不消失(或者存活时间长点)就能够在很长一段时间内把这个标识发送给Servlet了。此时Servlet就能够找到之前创建的session对象了。
【实现方案】
在servlet中手动创建JESSIONID;
手动设置JESSIONID的存活时间;
将JESSIONID响应给浏览器;

@WebServlet("/chi")
public class ChiServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //实现持久化session
        HttpSession session = request.getSession();
        //获取sessionid
        String id = session.getId();

        Cookie cookie = new Cookie("JSESSIONID",id);
        //是cookie持久化
        cookie.setMaxAge(60*30);

        //响应回浏览器
        response.addCookie(cookie);
    }
}

Servlet作用域总结

  • ServletContext域:
    一个WEB应用(项目)对应一个ServletContext,这个对象中保存的数据正在整个WEB项目中都有效;
    • 创建:服务器启动的时候;
    • 销毁:服务器关闭或项目移除后;
  • HttpSession:
    一次会话给客户端(浏览器)创建一个session。这个对象中保存的数据,一次会话(多次请求)内数据有效;
    • 创建:服务器第一次调用getSession()的时候;
    • 销毁:
      • 服务器非正常关闭(正常关闭:Session被序列化);
      • Session过期了:默认存活时间30分钟;
      • 手动调用session的invalidate()方法;
  • HttpServletRequest:
    一次请求创建一个request。这个对象中保存的数据,一次请求(请求链)内数据有效;
    • 创建:客户端向服务器发送一次请求;
    • 销毁:服务器为这次请求做出响应之后,销毁request;

【API操作】操作三个作用域对象的API

  • 存储数据:setAttribute(name,value);
  • 获得数据:getAttribute(name);
  • 删除数据:removeAttribute(name);