我试图理解scope
JSP动作标记中的jsp:useBean
属性是如何工作的。在我的理解中,scope
用于指示bean的位置(请求,会话,应用程序等),但经过一些测试后,我遇到了一个有趣的情况,并非如此,请考虑以下JSP代码(我在这里使用scriplets只是为了简单起见):
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" import="package2JSP.User" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Title</title>
</head>
<body>
<%
User user1 = new User("id1","name1");
User user2 = new User("id2","name2");
request.setAttribute("user", user1);
session.setAttribute("user", user2);
%>
<%-- Here I expect to create user bean that represents user2 from session scope--%>
<jsp:useBean id="user" class="package2JSP.User" scope="session"/>
<%-- Here I expect user name to be name2 but it is name1 instead--%>
<jsp:getProperty property="name" name="user"/>
</body>
</html>
所以基本上我在这里创建了2个用户对象并将它们设置为&#34; user&#34;请求和会话范围中的属性,当我尝试检索&#34; user&#34;来自&#34; session&#34;使用jsp:useBean
的范围好像&#34;用户&#34;来自&#34;请求&#34;范围已被检索。
你能解释一下为什么会这样吗?使jsp:useBean
以这种方式工作的开发理由是什么,而不是通常从指定范围中选择属性,它有什么优点吗?
现在我知道我可以使用JSTL / EL来检索所需的值,即<c:out value="${sessionScope.user.name}" />
,但我只是想知道jsp:useBean
的工作原理。
答案 0 :(得分:0)
在这种情况下涉及2个标签:
jsp:useBean
根据Specification - CHAPTER JSP.5 - JSP.5.1 <jsp:useBean>
:
jsp:useBean操作关联Java编程的实例 语言对象在给定范围内定义,可用于 给定id具有相同id的新声明的脚本变量。 在无脚本页面中或在脚本中使用操作时 无脚本上下文(如在所指示的动作的主体中),那里 没有创建Java脚本变量,而是EL变量 创建
编译的java代码是:
package2JSP.User user = null;
synchronized (session) {
user = (package2JSP.User) _jspx_page_context.getAttribute("user", PageContext.SESSION_SCOPE);
if (user == null){
try {
user = (package2JSP.User) java.beans.Beans.instantiate(this.getClass().getClassLoader(), "package2JSP.User");
} catch (ClassNotFoundException exc) {
throw new InstantiationException(exc.getMessage());
} catch (Exception exc) {
throw new ServletException("Cannot create bean of class " + "package2JSP.User", exc);
}
_jspx_page_context.setAttribute("user", user, PageContext.SESSION_SCOPE);
}
}
如果要访问此用户对象,可以使用scriptlet(表达式)<%=user.getName()%>
jsp:getProperty
根据Specification - CHAPTER JSP.5 - JSP.5.3 <jsp:getProperty>
说:
中的name属性的值 jsp:setProperty和jsp:getProperty将引用一个对象 是通过findAttribute从pageContext对象获得的 方法
JSP编译器从jsp:getProperty
标记调用findAttribute()
:
out.write(org.apache.jasper.runtime.JspRuntimeLibrary.toString(
(((package2JSP.User)_jspx_page_context.findAttribute("user")).getName())));
findAttribute()
在页面,请求,会话中搜索命名属性(如果有效), 和应用程序范围,并返回相关的值或 空。
基本上:返回第一场比赛。
使用useBean
和getProperty
被视为不良做法
使用JSTL / EL是处理属性的更好方法。