JavaBean 是如何查找属性的?它是否也只查看名称或范围?
How does JavaBean search for attribute? Does it look at just name or scope as well?
假设我有class个人:
package com.example;
public class Person {
private String name;
public String getName() {
return name;
}
public Person(String name) {
this.name = name;
}
public Person() {
}
}
我使用名为 MyServlet
的 Servlet 在请求范围内创建 Person 对象作为属性:
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Person p1 = new Person("Evan");
req.setAttribute("person", p1);
RequestDispatcher view = req.getRequestDispatcher("/result.jsp");
view.forward(req, resp);
}
}
最后,JSP 收到 forwarded 请求并尝试打印属性。请注意我是如何故意设置 scope="application"
而不是 scope="request"
而不是属性所在的位置:
<!DOCTYPE html>
<html><body>
<jsp:useBean id="person" class="com.example.Person" scope="application"/>
Welcome <jsp:getProperty name="person" property="name"/>
</body></html>
我预计 JSP 不会找到属性,因为我明确告诉它“搜索”位于 应用程序范围 中的属性,而我的属性位于 请求的范围。令我惊讶的是,我收到打印消息 Hello Evan
,这意味着它以某种方式找到了它。有人可以解释一下吗?
我也在阅读 Head First Servlets 和 JSP,在那里我遇到了这个(第 350 页)。此图(第 3 行)显示了它如何在 REQUEST_SCOPE 处搜索属性:
所以有人真的能帮我弄清楚它在搜索“人”时是如何找到我的属性的吗就在请求的范围内?
<jsp:getProperty>
的文档说:
The value of the name
attribute in jsp:setProperty
and jsp:getProperty
will refer to an object that is obtained from the pageContext
object through its findAttribute
method.
findAttribute(String name)
的 javadoc 说:
Searches for the named attribute in page, request, session (if valid), and application scope(s) in order and returns the value associated or null.
您的 <jsp:useBean>
可能使用默认构造函数创建了一个新实例,并将其分配给应用程序范围,但是 <jsp:getProperty>
从实例中检索到的值找到了请求范围,因为它看起来在那里首先.
我建议不要使用 <jsp:getProperty>
,而只使用 EL。
使用 EL 你会写 ${person.name}
。要强制指定范围,您可以使用前缀:
pageScope.
requestScope.
sessionScope.
applicationScope.
例如${applicationScope.person.name}
应该是 null
,因为应用程序范围实例是使用默认构造函数创建的。
注意: 将文本写入 HTML 文档时,并且文本源自用户,您应该始终将其转义。在将 JavaServer Pages 标准标记库 (JSTL) 正确添加到您的项目后,使用 <c:out value="${person.name}"/>
来做到这一点。
假设我有class个人:
package com.example;
public class Person {
private String name;
public String getName() {
return name;
}
public Person(String name) {
this.name = name;
}
public Person() {
}
}
我使用名为 MyServlet
的 Servlet 在请求范围内创建 Person 对象作为属性:
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Person p1 = new Person("Evan");
req.setAttribute("person", p1);
RequestDispatcher view = req.getRequestDispatcher("/result.jsp");
view.forward(req, resp);
}
}
最后,JSP 收到 forwarded 请求并尝试打印属性。请注意我是如何故意设置 scope="application"
而不是 scope="request"
而不是属性所在的位置:
<!DOCTYPE html>
<html><body>
<jsp:useBean id="person" class="com.example.Person" scope="application"/>
Welcome <jsp:getProperty name="person" property="name"/>
</body></html>
我预计 JSP 不会找到属性,因为我明确告诉它“搜索”位于 应用程序范围 中的属性,而我的属性位于 请求的范围。令我惊讶的是,我收到打印消息 Hello Evan
,这意味着它以某种方式找到了它。有人可以解释一下吗?
我也在阅读 Head First Servlets 和 JSP,在那里我遇到了这个(第 350 页)。此图(第 3 行)显示了它如何在 REQUEST_SCOPE 处搜索属性:
所以有人真的能帮我弄清楚它在搜索“人”时是如何找到我的属性的吗就在请求的范围内?
<jsp:getProperty>
的文档说:
The value of the
name
attribute injsp:setProperty
andjsp:getProperty
will refer to an object that is obtained from thepageContext
object through itsfindAttribute
method.
findAttribute(String name)
的 javadoc 说:
Searches for the named attribute in page, request, session (if valid), and application scope(s) in order and returns the value associated or null.
您的 <jsp:useBean>
可能使用默认构造函数创建了一个新实例,并将其分配给应用程序范围,但是 <jsp:getProperty>
从实例中检索到的值找到了请求范围,因为它看起来在那里首先.
我建议不要使用 <jsp:getProperty>
,而只使用 EL。
使用 EL 你会写 ${person.name}
。要强制指定范围,您可以使用前缀:
pageScope.
requestScope.
sessionScope.
applicationScope.
例如${applicationScope.person.name}
应该是 null
,因为应用程序范围实例是使用默认构造函数创建的。
注意: 将文本写入 HTML 文档时,并且文本源自用户,您应该始终将其转义。在将 JavaServer Pages 标准标记库 (JSTL) 正确添加到您的项目后,使用 <c:out value="${person.name}"/>
来做到这一点。