簡體   English   中英

Java servlet和JSP訪問同一個會話bean

[英]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,請按以下順序執行以下步驟:

  1. 嘗試使用您指定的范圍和名稱查找Bean。
  2. 使用您指定的名稱定義對象引用變量。
  3. 如果找到Bean,則在變量中存儲對它的引用。 如果指定了type,則為Bean提供類型。
  4. 如果找不到Bean,則從您指定的類中實例化它,在新變量中存儲對它的引用。 如果類名表示序列化模板,則Bean由java.beans.Beans.instantiate實例化。
  5. 如果已實例化(而不是定位)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())

另請參閱JSP規范JSP EL規范

更新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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM