访问同一个 session bean 的 Java servlet 和 JSP

标签 java jsp servlets

假设我有一个简单的登录 servlet,它检查传递的 name 并创建 User 对象并将其存储在 session 中。

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 bean 文档

To locate or instantiate the Bean, takes the following steps, in this order:

  1. Attempts to locate a Bean with the scope and name you specify.
  2. Defines an object reference variable with the name you specify.
  3. If it finds the Bean, stores a reference to it in the variable. If you specified type, gives the Bean that type.
  4. If it does not find the Bean, instantiates it from the class you specify, storing a reference to it in the new variable. If the class name represents a serialized template, the Bean is instantiated by java.beans.Beans.instantiate.
  5. If has instantiated (rather than located) the Bean, and if it has body tags or elements (between and ), executes the body tags.

问题:

Attempts to locate a Bean with the scope and name you specify

它没有指定“定位”过程。这是否意味着它将检查 HttpServletRequest.getSession() 或仅检查其他页面是否已创建此 bean?

If it does not find the Bean, instantiates it from the class you specify, storing a > reference to it in the new variable.

这实际上意味着 Jsp 可以使用 jsp_internal_name_user 将新创建的 bean 与 session 相关联。 没有关于 Jsp 如何在 session 中存储和查找 bean 的消息。

有一个选项可以使用 ${sessionScope.user} 访问 session 对象,这将保证从 Java session 对象中获取“用户”。和我自己装的一样。

Java EE 5 示例“Book Store”使用 ${sessionScope.name} 方法访问 session 对象。

仅使用 ${user} 即可。这就是让我担心的。我希望在规范中看到关于 locate 过程以及 ${user} 是否必须工作或是否取决于 JSP 和/或 JSTL 引用的特定句子实现。

最佳答案

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

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

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

但是,我也看到了它对纯文档很有用的论点。您可以声明“无用”jsp:useBean JSP 页面顶部的实例,以便您了解在特定 JSP 页面中使用了哪些模型。虽然我觉得它很聪明,但我自己从来不需要用这种方式在 JSP 中记录模型。根据评论,另一个论点确实是像 IDEA 和 Eclipse 这样的 IDE 能够自动完成 EL 中的 bean 属性。

更新:关于定位,使用 PageContext#findAttribute() 为此,然后使用反射/javabean 自省(introspection)来调用它的 getter 方法。例如

${user.name}

大致解析为

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

另见 JSP specificationJSP EL specification .

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

<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));
}

关于访问同一个 session bean 的 Java servlet 和 JSP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2663079/

相关文章:

http - 如何删除传输编码 : chunked in the HTTP response

java - 为什么 JNDI 返回带有 NULL uri 的数据源而不是查找失败?

java - 序列化时是否保留了实习字符串?

java - JSP:加入 2 个实体时出现 NumberFormatException

java - java-ee中if语句的逻辑问题

mysql - 使用 C3P0 的 Hibernate 在 Oracle 上运行良好,但不关闭与 MySQL 5.6 的连接

java - 在 Java Web 应用程序中设置当前请求的区域设置

java - 如何在java中添加新的系统属性

java - 计数器值在多线程中得到休息

Java 服务器页面参数混淆