【问题标题】:request.getSession() is getting session or creating session?request.getSession() 是获取会话还是创建会话?
【发布时间】:2013-09-06 06:27:33
【问题描述】:

我刚刚经历过,

Under what conditions is a JSESSIONID created?

到目前为止,我的印象是,

request.getSession()

根据传递给该方法的boolean 为我提供当前会话(给予,而不是创建)。直到这里看起来很酷。

现在我读到了

当您的代码第一次调用 request.getSession() 或 request.getSession(true) 时,会创建会话。

所以,如果我没有在我的任何servlets 中调用request.getSession(),并且这些 servlet 用于提供一些静态 html 页面(大约 50 个),

1)容器和客户端之间不需要session

2)如果没有,容器如何检测(服务于 html 页面)客户端?除了 session id 之外的标头中是否有任何隐藏信息?

【问题讨论】:

  • 你在哪里读到最后的报价?
  • @Beryllium 你说的是哪句话??
  • "当您的代码调用...时创建会话"
  • 是的,我已经阅读了您的问题。只是不清楚报价的来源。来自that answer
  • @Beryllium 是的,从第二句话开始。 :)

标签: java session servlets creation


【解决方案1】:

HttpSession 并不总是必需的。如果 servlet 是“无状态的”,并且来自 HTTP 请求的信息足以满足请求,情况就是如此。

如果您有不调用request.getSession() 的servlet,则不会创建HttpSession

一般来说,HttpSession 是必需的,如果 servlet 必须检测多个请求是否来自同一个客户端。例如在会话属性中管理会话状态(如购物车等)。


示例:telnet 到只返回文本/纯字符串的 servlet:bold 中的文本已被输入(即 HTTP 请求)

$ telnet 本地主机 8080
正在尝试 127.0.0.1...
已连接到 localhost.localdomain。
转义字符为 '^]'。
GET /xxx/textplainservlet/HTTP/1.1
主机:localhost:8080

HTTP/1.1 200 正常
服务器:Apache-Coyote/1.1
内容类型:text/plain;charset=ISO-8859-1
内容长度:13
日期:格林威治标准时间 2013 年 9 月 6 日星期五 12:11:10

你好,世界

在这种情况下不会创建会话。


示例:一个只返回静态 HTML 内容的简单 JSP:

GET /xxx/hello.jsp HTTP/1.1
主机:localhost:8080

HTTP/1.1 200 正常
服务器:Apache-Coyote/1.1
X-Powered-By:JSP/2.2
设置 Cookie:JSESSIONID=n0cOaZFUvlXSvX7hNEfcNzHP.undefined;路径=/nk-eapp-ping-60-jpa
内容类型:text/html;charset=ISO-8859-1
内容长度:49
日期:格林威治标准时间 2013 年 9 月 6 日星期五 12:11:58

[... HTML 文档 ...]

在这种情况下,会创建一个会话,并设置 cookie,即使 JSP 没有显式调用 request.getSession()

因此我附上了HttpSessionListener,实际上,会话是隐式创建的。在那个监听器中,我转储了一个堆栈跟踪:

org.apache.catalina.session.StandardSession.tellNew(StandardSession.java:374)
org.apache.catalina.session.StandardSession.setId(StandardSession.java:344)
org.apache.catalina.session.ManagerBase.createSession(ManagerBase.java:506)
org.apache.catalina.session.StandardManager.createSession(StandardManager.java:297)
org.apache.catalina.connector.Request.doGetSession(Request.java:2665)
org.apache.catalina.connector.Request.getSession(Request.java:2375)
org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:841)
org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:852)
org.apache.jasper.runtime.PageContextImpl._initialize(PageContextImpl.java:146)
org.apache.jasper.runtime.PageContextImpl.initialize(PageContextImpl.java:124)
org.apache.jasper.runtime.JspFactoryImpl.internalGetPageContext(JspFactoryImpl.java:106)
org.apache.jasper.runtime.JspFactoryImpl.getPageContext(JspFactoryImpl.java:62)
org.apache.jsp.hello_jsp._jspService(hello_jsp.java:45)

这些测试是使用 JBoss 7 运行的。


要检查是否创建了会话,只需在您的环境中使用 HttpSessionListener 重新测试它:

@WebListener
public class MyHttpSessionListener implements HttpSessionListener {
    private final static Logger log = Logger
            .getLogger(MyHttpSessionListener.class.getName());

    public void sessionCreated(HttpSessionEvent e) {
        // Possibly create a stack trace here, and dump it
        log.info("Session created: " + e.getSession().getId() + ", timeout "
                + e.getSession().getMaxInactiveInterval());
    }

    public void sessionDestroyed(HttpSessionEvent e) {
        log.info("Session destroyed: " + e.getSession().getId());
    }
}

【讨论】:

    【解决方案2】:

    1)容器和客户端之间不需要会话吗?

    ---> 如果只是 html 页面,则不需要,例如JavaDocs html 页面,您不需要创建会话。

    2)如果没有,容器如何检测(服务于 html 页面)客户端?除了会话 ID 之外的标头中的任何隐藏信息?

    ----> 它是 URL,您将 url 映射到 html 页面,或者您只是将您的页面保持为公共访问。在这里,如果请求被命中,tomcat 将创建线程,该线程将通过写入请求页面来响应请求。

    看看HTTP Request header

    【讨论】:

      猜你喜欢
      • 2012-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-13
      • 1970-01-01
      • 2017-07-07
      • 1970-01-01
      • 2012-01-03
      相关资源
      最近更新 更多