【问题标题】:Detecting a new HttpSession检测新的 HttpSession
【发布时间】:2013-11-09 20:20:58
【问题描述】:

我是 J2EE 的新手,并且卡在会话管理中。根据规范,HttpSession 的 isNew() 方法如果没有之前创建,则返回 true 来自客户端的 sessionID 存储在服务器上。 我已经运行了以下代码,即使在第一次执行时 isNew() 方法也没有返回 true。到目前为止,我已经尝试了以下事情:

  1. 删除了我的浏览器历史记录(一切……我正在使用 Firefox)。
  2. 从 Netbeans 7.3.1 构建并运行我的 Web 应用程序。在这种情况下,会生成一个新的 Session ID,但 isNew() 方法肯定不会返回 true。
  3. 重新启动 PC(虽然这样做很愚蠢)。

我的问题是,我应该怎么做才能执行 servlet 代码中的 if (session.isNew()){} 块(包括浏览器的任何设置以及其他任何内容)? 我的代码有什么问题?

下面是我的代码..

初始视图的代码:: index.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <h1>Welcome to color selection page</h1>
        <form method="POST"
              action="NewPattern">
            Select beer characteristics<br>
                Color:
                <select name="color" size="1">
                    <option value="light">light</option>
                    <option value="amber">amber</option>
                    <option value="brown">brown</option>
                </select>
                <br>
                <input type="SUBMIT">
        </form>
    </body>
</html>

servlet 的代码::

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class NewServlet extends HttpServlet {
    protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        HttpSession session = request.getSession();
        try {
            out.println("<!DOCTYPE html>");
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet NewServlet</title>");            
            out.println("</head>");
            out.println("<body>");

            if (session.isNew())
                out.println("It is a new session.  Session ID: " + request.getSession());
            else
                out.println("It is not a new session.  Session ID: " + request.getSession());

            out.println("<h1>Got your chosen color " + request.getParameter("color") + "</h1>");
            out.println("</body>");
            out.println("</html>");
        }
        finally {            
            out.close();
        }
    }
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        processRequest(request, response);
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        processRequest(request, response);
    }
    @Override
    public String getServletInfo() {
        return "Short description";
    }
}

DD 代码::

<?xml ...>
<web-app ...>
    <servlet>
        <servlet-name>ServletNew</servlet-name>
        <servlet-class>NewServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletNew</servlet-name>
        <url-pattern>/NewPattern</url-pattern>
    </servlet-mapping>
</web-app>

【问题讨论】:

  • 您基本上使用了错误的解决方案来满足您心中的功能需求。您不应该检查会话是否是在当前请求中创建的。相反,检查是否正在设置一个属性,如果没有,则将其视为“新”,然后设置 that 属性,以便后续请求可以对其进行拦截。

标签: java jsp jakarta-ee servlets httpsession


【解决方案1】:

问题是你先访问index.jsp,然后访问servlet。

服务器很可能会在您访问的第一个资源处创建会话,因此会话是 index.jsp 上的新会话。 servlet 之后会被访问,因此会话不再是新的。

您基本上可以通过清理会话 cookie 来测试您的代码,并通过手动输入其 URL 直接在浏览器中打开 servlet。

我还建议安装 Firefox 插件“Firebug”,它有一个网络控制台,您可以在其中查看对服务器的每个请求,包括所有传输的数据。 (另一个很棒的插件是“Web Developer Toolbar”,它可以很容易地只清理会话 cookie。)

根据您要实现的目标,您要么需要重新考虑页面流程,要么考虑使用像 Struts 这样的 Web 框架。

【讨论】:

  • JSP总是创建会话,除非明确配置不这样做。您需要使用 (或等效项)来禁用此功能。
【解决方案2】:

为了检测新会话的创建,您需要实现HttpSessionListener

在您的web.xml 中配置它

<listener>
    <listener-class>com.my.pack.age.MyHttpSessionListener</listener-class>
</listener>

如果使用 servlet 规范 3.0,则使用 @WebListener 注释类

当容器创建会话时,它会触发方法sessionCreated,下一次调用isNew() 将返回true

要回答这个问题 - 并重复 jCoder 所说的 - 在调用 JSP 时已经创建了会话。 servlet 容器为每个 JSP 生成一个 servlet,如果您查看该代码,您会发现在此时创建的会话(如果尚未创建)已经发生了对 getSession() 的调用。当您的servlet 然后调用方法getSession() 时,会话返回者是通过JSP-servlet 创建的。因此它总是返回false

tomcat生成的示例Servlet代码sn-p

response.setContentType("text/html; charset=ISO-8859-15");
pageContext = _jspxFactory.getPageContext(this, request, response,
            null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession(); // session is created here
out = pageContext.getOut();
_jspx_out = out;

在实际配置中,块if (session.isNew()){} 将永远不会被执行。如果您想在创建会话时执行一些操作,则创建并配置会话侦听器或配置您的会话以创建一个seesion - 正如 MarkThomas 所建议的那样 - 以便您的 servlet 中的块 if (session.isNew()){} 可以执行。

【讨论】:

  • 不回答问题。 isNew() 仍然是 isNew()。添加会话侦听器不会改变这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-08
  • 2021-09-13
  • 2012-10-12
相关资源
最近更新 更多