代码之家  ›  专栏  ›  技术社区  ›  Mykola Golubyev

JavaServlet和JSP访问同一会话bean

  •  10
  • Mykola Golubyev  · 技术社区  · 15 年前

    假设我有一个简单的登录servlet,它检查通过的 name 创造 User 对象并将其存储在会话中。

    User user = new User();
    user.setId(name);
    
    request.getSession().setAttribute("user", user);
    response.sendRedirect("index.jsp");
    

    index.jsp 第一页通过 jsp:useBean

    <jsp:useBean id="user" scope="session"
                 class="package.name.User"/>
    
    <div class="panel">
        Welcome ${user.id}
    </div>
    

    到目前为止还有效。

    来自jsp beans文档

    要定位或实例化bean, 采取以下措施 步骤,按此顺序:

    1. 尝试使用指定的作用域和名称定位bean。
    2. 使用指定的名称定义对象引用变量。
    3. 如果它找到bean,则在变量中存储对它的引用。如果 你指定了类型,给bean 那种类型。
    4. 如果找不到bean,则从 指定,将对它的引用存储在 新变量。如果类名 表示序列化模板, bean由 实例化。
    5. if已实例化(而不是定位)bean,并且if 它有主体标记或元素(在 and ), 执行主体标记。

    问题是:

    尝试使用指定的作用域和名称定位bean

    它没有指定“定位”进程。是否意味着它会检查 HttpServletRequest.getSession() 或者只是检查其他页面是否已经创建了这个bean?

    如果找不到bean,则从指定的类实例化它,并在新变量中存储对它的>引用。

    这实际上意味着jsp可以使用 jsp_internal_name_用户 . 目前还没有关于jsp如何在会话中存储和查找bean的消息。

    有一个选项可以通过使用 ${sessionScope.user} 这将确保从Java会话对象获得“用户”。和我自己放的一样。

    JavaEE 5示例“书店”访问会话对象使用 ${sessionScope.name} 方法。

    只使用 ${user} 作品。这就是我担心的。我想在说明书中看到一个关于 locate 过程和是否 {用户} 必须工作,或者是由jsp和/或jstl引用实现决定。

    3 回复  |  直到 10 年前
        1
  •  6
  •   Balder    10 年前

    对于负责模型的控制器(servlet),则 jsp:useBean 仅当默认实例(使用无参数构造函数构造)公开的行为/状态与不存在的实例不同时才有用。例如,如果您希望使用默认用户名“未知用户”,您可以:

    public User {
        this.id = "Unknown User";
    }
    

    否则,最终用户可能会面对“欢迎”而不是“欢迎未知用户”的显示。在您的特定情况下,您可以安全地删除它。这是多余的。

    然而,我也看到了这样一个论点:它对于纯文档很有用。你可以说“没用” 使用JSP 在jsp页面顶部的实例,这样您就可以了解在特定jsp页面中到底使用了哪些模型。尽管我觉得它非常聪明,但我自己从来没有必要用这种方式在jsp中记录模型。根据评论,另一个论点是ide的idea和eclipse能够自动完成el中的bean属性。

    更新 :至于定位,它使用 PageContext#findAttribute() 然后使用reflection/javabean内省来调用它的getter方法。例如。

    ${user.name}
    

    大致决定

    out.print(pageContext.findAttribute("user").getName())
    

    也看到 JSP specification 以及 JSP EL specification .

    更新2 : <jsp:useBean> 当然 不使用内部名称或作为会话属性前缀。循环遍历所有会话属性以查看实际的键和值:

    <c:forEach items="${sessionScope}" var="entry">
        ${entry.key} = ${entry.value}<br>
    </c:forEach>
    

    或者在一个servlet中

    for (String name : Collections.list(session.getAttributeNames())) {
       System.out.println(name + " = " + session.getAttribute(name));
    }
    
        2
  •  4
  •   evnafets    15 年前

    引用jsp规范jsp.5.1

    基本语义尝试使用id和 范围。如果找不到对象,它将尝试使用另一个 属性。

    换句话说,

    <jsp:useBean id="user" scope="session" class="package.name.User"/>
    

    大致可以翻译成Java:

    package.name.User user = (package.name.User)session.getAttribute("user");
    if (user == null){
      user = new package.name.User();
      session.setAttribute("user", user);
    }
    
        3
  •  2
  •   lexicore    15 年前

    从文档中:

    这个 <jsp:useBean> 元素定位或实例化JavaBeans组件。 <jsp:usebean> 第一次尝试定位bean的实例。 如果豆子不存在, <jsp:usebean> 从类实例化或序列化 模板。

    既然“定位”bean是完全正确的,那么我们可以假设该bean可以通过除通过 <jsp:usebean> . 例如,通过在servlet中创建它。