我正在阅读head first servlet和jsp,其中一个servlet有代码:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
foo.Person p = new foo.Person("Evan");
req.setAttribute("person", p);
RequestDispatcher view = req.getRequestDispatcher("/result.jsp");
view.forward(req, resp);
}
后来,他们展示了如何使用 <jsp:useBean>
以及 <jsp:useProperty>
要获取人员姓名:
我想我明白了-如果请求范围中没有属性,则表示变量person将为null,这也意味着将使用默认构造函数创建新的person对象。底线:我没有我的属性。幸运的是,我以前将person对象存储在请求的作用域中,这意味着它会找到它。
所以我想尝试一下,修改一下代码。而不是 <jsp:useBean id="person" class="foo.Person" scope="request"/>
,我打字 <jsp:useBean id="person" class="foo.Person" scope="application"/>
. 请记住,我们的属性以前存储在请求的作用域中,而不是应用程序中,这意味着person将为null。令我惊讶的是,它很容易找到属性并打印出来 Evan
. 当这本书清楚地显示它将在我在scope's attribute中所写的同一范围内搜索属性时,这是怎么发生的?
2条答案
按热度按时间wgxvkvu91#
检查以下描述
<jsp:getProperty>
从javaserver页面™规范中name属性的值jsp:setproperty and jsp:getproperty will 引用通过pagecontext对象的findattribute方法从其获取的对象。
现在,检查一下
findAttribute
在同一份文件中:按顺序搜索页、请求、会话(如果有效)和应用程序范围中的命名属性,并返回关联的值或null。
因此,如果属性,
person
在中找不到request
范围,搜索范围扩展到application
范围。<jsp:useBean id="person" class="foo.Person" scope="application"/>
将创建一个新的Person
把它放进application
无论此属性是否已存在于request
范围。当你使用
<jsp:getProperty name="person" property="name">
,搜索属性,person
将按顺序在页面>请求>会话(如果有效)>应用程序范围中执行,并采用“查找优先”方法,即,一旦找到,就返回值(即不再进行进一步搜索)。既然你有两个
Person
属性为的对象person
:一个有名字,Evan
在request
范围,另一个作为new Person()
在application
范围,在request
作用域是如何返回的findAttribute
作品。ecfdbz9o2#
关键在于
<jsp:useBean>
如果在指定的范围内找不到对象,也可以创建对象。这意味着:如果对象不在你说的范围内,
<jsp:useBean>
将创建一个新对象。如果物体在你说的范围内,
<jsp:useBean>
将使用该对象。换句话说,您可以处理一个对象或两个对象,这取决于您将对象放置在哪个上下文中,以及您所说的对象是在哪个上下文中。
我知道,这让人困惑。我们来举几个例子。我将对person类进行一些分解,以显示对象是在哪里创建的。
第一个示例:范围匹配
servlet内容:
测试.jsp:
访问servlet将导致以下输出:
查看前两行,您将看到在servlet中只创建了一个对象。这个
<jsp:useBean>
就这一个。第二个示例:范围不匹配
servlet保持不变:
jsp现在使用应用程序范围,而不是实际人员所在的会话范围:
结果是:
现在有两个对象。一个是由servlet创建的,如第一个示例所示,另一个是由jsp生成的servlet创建的,因为
<jsp:useBean>
在应用程序范围中找不到对象,因此它使用class
属性创建一个。混乱是由
<jsp:getProperty>
在作用域中搜索对象page > request > session > application
,直到它找到一个。这和什么是分开的<jsp:useBean>
是(如上两个例子所述)。如有疑问,请参阅jsp规范。
说到这里,请注意
<jsp:useBean>
以及<jsp:getProperty>
在实践中并不是很常用。人们使用jsp表达式语言、jstl或其他(更强大的)自定义标记。为了从书本中学习并避免使用scriptlet(这是一种糟糕的做法),可以从这些脚本开始,但实际上它们并不是人们最喜欢的访问对象及其属性的方式。