【问题标题】:Servlet data members keep session?Servlet 数据成员保持会话?
【发布时间】:2011-07-22 08:33:52
【问题描述】:

我正在从现有项目构建一个 Web 应用程序。在现有项目中,我有一个类,其中包含我的所有对象以及我可以用它们做的事情。 我想知道如果我将这个类的一个实例作为一个 servlet 的数据成员会发生什么:

  1. 当具有相同会话的同一用户被定向到包含此类的 servlet 时,它将保留其数据还是每次都重新生成?
  2. 每个用户/会话是否会有此成员的不同副本或是否共享?
  3. 如果 servlet 中的数据成员在同一会话中不保持其状态,那么您有什么建议?也许主动将其添加到会话中?

感谢您的帮助

【问题讨论】:

    标签: java session servlets


    【解决方案1】:

    Servlet - 因此它们的数据成员 - 在服务器上的所有会话之间共享。因此

    当具有相同会话的同一用户被定向到包含此类的 servlet 时,它将保留其数据还是每次都重新生成?

    在您重新启动 Web 应用程序之前,数据将保留(对于所有用户)。

    每个用户/会话是否会有此成员的不同副本或是否共享?

    它是共享的。

    如果 servlet 中的数据成员在同一会话中不保持其状态,那么您有什么建议?也许主动将其添加到会话中?

    会话特定数据应存储在HttpSession 中。

    【讨论】:

    • 只是为了确保我理解正确:如果我有一个 String 类型的 servlet 数据成员,它为一个用户保留错误文本,如果另一个用户从不同的浏览器连接,他会得到同样的错误文本?我的印象是,由于 servlet 用于动态页面,每个用户都有自己的版本......
    • @Ran,是的,其他用户将收到相同的错误文本。每个 Web 应用程序只有一个 servlet 实例,服务于所有请求(在不同的线程中),而且 servlet 甚至不是线程安全的。参见例如this thread 了解更多详情。
    【解决方案2】:

    为了确定这种行为,我写了一点TestingServlet - 我将向您展示 servlet 及其成员的生命周期。还提供;如何使用会话变量

    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * Basic servlet for lifecycle testing
     * 
     * @author powermicha
     * 
     */
    public class TestingServlet extends HttpServlet {
    
        /**
         * 
         */
        private static final long serialVersionUID = 4020575563844924588L;
    
        private Logger logger;
    
        private int requestCounter;
    
        @Override
        public void init() throws ServletException {
            logger = Logger.getLogger("TestingServlet_" + System.currentTimeMillis());
            logger.log(Level.INFO, "TestingServlet initialized");
    
            requestCounter = 0;
        }
    
        @Override
        public void destroy() {
            logger.log(Level.INFO, "TestingServlet destroyed");
        }
    
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
            int requestsPerSession = incrementRequestsPerSession(req);
    
            String logMessage = "TestingServlet was called " + (++requestCounter) + " times. " 
                    + requestsPerSession + " times from the same session (ID:"
                    + req.getSession().getId() + ")";
    
            logger.log(Level.INFO, logMessage);
    
            // send it to the browser
            PrintWriter writer = resp.getWriter();
            writer.write(logMessage);
            writer.close();
        }
    
        private int incrementRequestsPerSession(HttpServletRequest req) {
    
            Integer counter = (Integer) req.getSession().getAttribute("requestsPerSession");
            if (counter == null) {
                counter = 1;
            } else {
                counter++;
            }
    
            req.getSession().setAttribute("requestsPerSession", counter);
    
            return counter;
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-02
      • 1970-01-01
      • 1970-01-01
      • 2013-10-29
      • 1970-01-01
      • 2012-11-05
      • 2011-10-29
      相关资源
      最近更新 更多