[英]Java servlet and JSP accessing the same session bean
假設我有一個簡單的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,則在變量中存儲對它的引用。 如果指定了type,則為Bean提供類型。
- 如果找不到Bean,則從您指定的類中實例化它,在新變量中存儲對它的引用。 如果類名表示序列化模板,則Bean由java.beans.Beans.instantiate實例化。
- 如果已實例化(而不是定位)Bean,並且它具有正文標記或元素(在和之間),則執行body標記。
問題:
嘗試使用您指定的范圍和名稱查找Bean
它沒有指定“定位”過程。 這是否意味着它會檢查HttpServletRequest.getSession()
或只是檢查其他頁面是否已經創建了這個bean?
如果找不到Bean,則從您指定的類中實例化它,在新變量中存儲>引用它。
這實際上意味着Jsp可以使用jsp_internal_name_user將新創建的bean與會話相關聯。 沒有關於Jsp如何在會話中存儲和查找bean的消息。
有一個選項可以使用${sessionScope.user}
來訪問會話對象,這將保證來自Java會話對象的“用戶”。 我自己投入的那個。
Java EE 5示例“Book Store”使用${sessionScope.name}
方法訪問會話對象。
僅使用${user}
。 這就是讓我擔心的問題。 我希望在規范中看到一個關於locate
過程的特定句子,以及${user}
是否必須工作或者是否由JSP和/或JSTL參考實現決定。
如果控制器(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方法。 例如
${user.name}
大致解決了
out.print(pageContext.findAttribute("user").getName())
更新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));
}
引用JSP規范JSP.5.1
基本語義嘗試使用id和scope查找現有對象。 如果未找到該對象,它將嘗試使用其他屬性創建對象。
換一種說法,
<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);
}
從文檔:
<jsp:useBean>
元素定位或實例化JavaBeans組件。<jsp:useBean>
首先嘗試查找Bean的實例。 如果Bean不存在,<jsp:useBean>
會從類或序列化模板中實例化它。
由於“定位”bean完全沒問題,因此我們可以假設bean可以通過<jsp:useBean>
實例化以外的方式使用。 例如,通過在servlet中創建它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.