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}"/> 来做到这一点。