假设我有一个简单的Login 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, 采取以下措施 步骤,按此顺序:
- 尝试使用您指定的范围和名称查找Bean。
- 使用您指定的名称定义对象引用变量。
- 如果找到Bean,则在变量中存储对它的引用。如果 你指定了类型,给出了Bean 那种。
- 如果找不到Bean,请从类中实例化它 指定,存储对它的引用 新变量。如果是班级名称 代表一个序列化的模板, Bean由实例化实例化 java.beans.Beans.instantiate联合。
- 如果已实例化(而非定位)Bean,以及是否 它有身体标签或元素(之间 和), 执行身体标签。
醇>
问题:
尝试使用您指定的范围和名称查找Bean
它没有指定“定位”过程。这是否意味着它会检查HttpServletRequest.getSession()
或只是检查其他页面是否已经创建了这个bean?
如果找不到Bean,请从您指定的类中实例化它,并存储&gt;在新变量中引用它。
这实际上意味着Jsp可以使用 jsp_internal_name_user 将新创建的bean与会话相关联。 没有关于Jsp如何在会话中存储和查找bean的信息。
有一个选项可以使用${sessionScope.user}
访问会话对象,这将保证来自Java会话对象的“用户”。我自己投入的那个。
Java EE 5示例“Book Store”使用${sessionScope.name}
方法访问会话对象。
仅使用${user}
作品。这就是让我担心的问题。我希望在规范中看到关于locate
进程的特定句子,以及${user}
是否必须有效,或者是否由JSP和/或JSTL参考实现决定。
答案 0 :(得分:6)
如果控制器(servlet)负责模型,jsp:useBean
仅在默认实例(使用no-arg构造函数构造)公开不同的行为/状态时才有用。实例。例如。如果您希望使用默认用户名“未知用户”,则可以执行以下操作:
public User {
this.id = "Unknown User";
}
否则,最终用户可能会面对“欢迎”而不是“欢迎未知用户”显示。在您的特定情况下,您可以安全地删除它。这是多余的。
但是,我也看到了它对纯文档有用的论点。您可以在JSP页面顶部声明“无用的”jsp:useBean
实例,以便您可以概览在特定JSP页面中使用的模型。虽然我发现它非常聪明,但我自己从未需要这种在JSP中记录模型的方法。根据评论,另一个论点确实是IDE这样的IDEA和Eclipse能够在EL中自动完成bean属性。
更新:关于定位,它使用PageContext#findAttribute()
,然后使用reflection / javabean introspection来调用getter方法。 E.g。
${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));
}
答案 1 :(得分:4)
引用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);
}
答案 2 :(得分:2)
来自文档:
<jsp:useBean>
元素定位或实例化JavaBeans组件。<jsp:useBean>
首先尝试查找Bean的实例。 如果Bean不存在,<jsp:useBean>
将从类或序列化实例化它 模板。
由于“定位”bean完全没问题,因此我们可以假设bean可以通过<jsp:useBean>
实例化以外的方式使用。例如,通过在servlet中创建它。