zoukankan      html  css  js  c++  java
  • Tomcat 之session 持久化1

    Tomcat 之session 持久化原理

    几个概念:

    Manager 接口,其实就是指的是对  其Sesison 的管理, 其默认实现是StandardManager (内部没有任何Store对象实例,而仅仅是通过 File 序列化实现的),它其实就是把session 保存到了本地的名为SESSIONS.ser 的文件;另外有PersistentManager,保存到本地文件(内部有一个FileStore)或数据库表(通过JDBCStore)。 除此之外,还有提供 集群的BackupManager 等。

    Store 则是专门指的是对Session 的存储接口。

    Store 有几个实现, 一是基于本地文件的实现: FileStore, 另外一个是基于数据库的实现: JDBCStore。 当然,这里是没有内存的实现的, 试想,基于的内存的话,又如何做持久化呢? 

    大致的原理:

    Tomcat 是怎么具体实行 session 持久的呢? 这样的, 当我们访问某个web 应用的时候,然后进行某些操作,这样Session里面会存在一些属性,然后我们关闭tomcat,tomcat会把session 通过  Manager  写到本地会数据库中,然后我们启动tomcat,tomcat会通过 Manger 恢复原先持久化的 Session相关属性( 不管是StandardManager ,PersistentManager 都是这样)。

    注意,这里我们必须要对某个web 应用做一些操作, 这样, tomcat才会对应的分配一个 session, 否则session不存在, 自然, 也是无法持久化的; 另外 我们必须优雅的关闭tomcat, 这样tomcat才会有机会在shutdown的时候 将session持久化。 通过 ctrl + c 或 shutdown脚本都是可以的, 但是 直接 kill, 是不行的。

    Tomcat 的session 持久,默认是支持的, 好奇怪,竟然一直没有发现! 那让我们做个测试吧!

    简单测试:

    这里我做了个简单的测试。怎么测试呢?

    思路:

    就是通过LkServlet 对Session写入一些东西, 然后停掉tomcat,再启动tomcat,看tomcat 是否能够把session恢复过来。 

    怎么看它是否能够恢复呢?  那就是 重启后, 直接访问SomeServlet, 通过SomeServlet 读取 Session的 attribute, 读取到了就是说明恢复成功,否则就是说明失败。

    写session的 servlet:

    package com.lk;
    
    import java.io.IOException;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class LkServlet extends HttpServlet {
        
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            // TODO Auto-generated method stub
            doPost(req, resp);
        }
        
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            
            String username = req.getParameter("username");
            String password = req.getParameter("password");
            
            if ("aa".equals(username) && "bb".equals(password)) {
                req.getRequestDispatcher("index.jsp").forward(req, resp);
                User user = new User();
                user.setUsername(username);
                user.setPassword(password);
                
                req.getSession().setAttribute("user", user); // 这里的user 必须实现Serializeable 接口, 否则无法恢复
                req.getSession().setAttribute("aaa", "AAAAAA");// 普通 字符串属性
                req.getSession().setAttribute("bb", 111);  // 普通 数值属性
                req.getSession().setAttribute("ccc", "how are you ! 你好啊 ! ");
            }
        }
    
    }

    测试用的 Servlet:

    package com.lk;
    
    import java.io.IOException;
    import java.util.Enumeration;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    public class SomeServlet extends HttpServlet {
        
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            // TODO Auto-generated method stub
            doPost(req, resp);
        }
        
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {
            
            HttpSession session = req.getSession();
            Enumeration<String> attributeNames = session.getAttributeNames();
            while (attributeNames.hasMoreElements()) {
                String string = (String) attributeNames.nextElement();
                System.out.println( string  + "               SomeServlet     "    +  session.getAttribute(string));
            }
    
            req.getRequestDispatcher("sess.jsp").forward(req, resp);
        }
    
    }

    其中:

    package com.lk;
    
    import java.io.Serializable;
    
    public class User implements Serializable {
    
    
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        
        
        @Override
        public String toString() {
            return "User [username=" + username + ", password=" + password + "]";
        }
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
        private String username;
        private String password;
    
        
    }

    这里的User 是必须实现Serializable 接口的, 否则呢, tomcat 是不能够它持久到 本地文件或 数据库中去的。 不过奇怪的是, 不实现虽然不能进行持久化,却也不报错, 这个让我开始测试的时候, 迷惑了很久, 还以为是我哪里配置的问题呢!!

    但是 其他的一些基本属性倒是 默认支持的。

    web.xml 配置:

      <servlet>
          <servlet-name>aaa</servlet-name>
          <servlet-class>com.lk.LkServlet</servlet-class>
      </servlet>
      
      <servlet-mapping>
          <servlet-name>aaa</servlet-name>
          <url-pattern>/lk</url-pattern>
      </servlet-mapping>
      
        
      
      <servlet>
          <servlet-name>ss</servlet-name>
          <servlet-class>com.lk.SomeServlet</servlet-class>
      </servlet>
      
      <servlet-mapping>
          <servlet-name>ss</servlet-name>
          <url-pattern>/ss</url-pattern>
      </servlet-mapping>
      

    重启后立即访问 http://localhost/ktb/ss , 结果:

    十月 29, 2017 2:03:17 下午 org.apache.coyote.AbstractProtocol start
    信息: Starting ProtocolHandler ["http-bio-80"]
    十月 29, 2017 2:03:17 下午 org.apache.coyote.AbstractProtocol start
    信息: Starting ProtocolHandler ["ajp-bio-8019"]
    十月 29, 2017 2:03:17 下午 org.apache.catalina.startup.Catalina start
    信息: Server startup in 2942 ms
    aaa                     SomeServlet     AAAAAA
    bb                      SomeServlet     111
    ccc                     SomeServlet     how are you ! 你好啊 !
    user                    SomeServlet     User [username=aa, password=bb]

    可见恢复成功!

     参考:

    http://www.cnblogs.com/fx2008/p/4148389.html

  • 相关阅读:
    LevelDB的源码阅读(二) Open操作
    LevelDB的源码阅读(一)
    Linux上leveldb的安装和使用
    Linux下安装jdk8的详细步骤
    Linux下用ls和du命令查看文件以及文件夹大小
    pytorch实现VAE
    Caffe实现VAE
    pytorch实现DCGAN、pix2pix、DiscoGAN、CycleGAN、BEGAN以及VAE
    PyTorch教程之Training a classifier
    PyTorch教程之Neural Networks
  • 原文地址:https://www.cnblogs.com/FlyAway2013/p/7750068.html
Copyright © 2011-2022 走看看