首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JSP 內置標簽深度解析:useBean、setProperty、getProperty 實現 JavaBean 與 JSP 無縫整合

     編輯:Java 相關知識

JSP 標準動作標簽:讓 JavaBean 成為頁面邏輯的「原住民」

JSP 規範定義了三個核心動作標簽 <jsp:useBean>、<jsp:setProperty>、<jsp:getProperty>,使 JavaBean 能以聲明式方式融入 JSP 頁面,實現「業務邏輯封裝在 Bean,頁面僅負責調用與展示」的分離。本文深度解析三大標簽的語法、屬性、作用域機制、類型轉換規則及最佳實踐。

一、<jsp:useBean>:聲明 Bean 實例與作用域

完整語法

<jsp:useBean id="beanId" 
              scope="page | request | session | application"
              class="package.ClassName"
              type="package.InterfaceOrSuperClass"
              beanName="package.BeanName" 
              >
    <!-- 初始化體:僅在 Bean 首次創建時執行 -->
    <jsp:setProperty name="beanId" property="*" />
</jsp:useBean>

核心屬性詳解

屬性必填說明
id是頁面內唯一變量名,對應 scripting variable (如 beanId.property)。區分大小寫。
scope否 (默認 page)生命週期範圍:
page 僅當前頁請求有效 (含 include/forward)
request 請求範圍 (forward 共享)
session 用戶會話範圍
application 全局應用範圍 (ServletContext)
class二選一具體實現類全限定名,需有公共無參構造器。容器調用 new ClassName() 實例化。
type二選一聲明類型 (接口/父類)。若單獨使用 type,Bean 必須已存在於指定 scope 中 (不創建新實例)。
beanName二選一配合 type 使用。通過 java.beans.Beans.instantiate() 實例化,支持序列化 Bean (.ser 文件) 或類名。

執行邏輯:查找或創建

  1. 在指定 scope 中查找 id 同名對象。
  2. 找到且類型兼容 (isInstance) → 直接使用,**不再創建**,body 體不執行。
  3. 未找到 → 根據 class/beanName 實例化 → 存入 scope → 執行 body 體 (通常放 setProperty 初始化)。

類型轉換規則 (type vs class)

<!-- 情況 1:class + type (類型寬化) -->
<jsp:useBean id="dao" class="com.impl.UserDaoImpl" type="com.dao.UserDao" scope="request" />
<%-- 頁面中 dao 變量類型為 UserDao 接口,實際對象為 UserDaoImpl --%>

<!-- 情況 2:僅 type (依賴現有對象) -->
<jsp:useBean id="user" type="com.model.User" scope="session" />
<%-- 須確保 session 中已有 "user" 屬性且為 User 實例,否則拋 InstantiationException --%>

二、<jsp:setProperty>:自動/手動注入屬性值

語法變體

<!-- 1. 自動匹配:請求參數名 = Bean 屬性名,自動調用 setter -->
<jsp:setProperty name="beanId" property="*" />

<!-- 2. 指定屬性自動匹配參數 -->
<jsp:setProperty name="beanId" property="username" />

<!-- 3. 參數名與屬性名不同 -->
<jsp:setProperty name="beanId" property="userName" param="username" />

<!-- 4. 直接指定固定值 -->
<jsp:setProperty name="beanId" property="status" value="active" />

核心機制

  • property="*":遍歷 request.getParameterNames(),對每個參數名 p,若 Bean 有 setP(Type),則調用 bean.setP(request.getParameter(p))。類型轉換自動處理 (String -> 基本類型/String/Date 等,遵循 JavaBeans 規範 PropertyEditor)。
  • param 屬性:顯式映射請求參數名 → Bean 屬性名。
  • value 屬性:靜態值或運行時表達式 <%= expr %> (JSP 1.x) / ${expr} (JSP 2.0 EL)。
  • 互斥性:param 與 value 不能同時使用。
  • 空值處理:請求參數為空字符串 ("") 時,不調用 setter,保留 Bean 默認值。

三、<jsp:getProperty>:輸出屬性值到響應流

語法

<jsp:getProperty name="beanId" property="propertyName" />

執行細節

  1. 在頁面上下文 (page/request/session/application 順序) 查找 name 對象。
  2. 調用對應 Getter 方法 getPropertyName()。
  3. 將返回值 轉為 String (toString(),基本類型轉包裝類再 toString)。
  4. 寫入隱含 out 對象 (相當於 out.print(value))。

前置條件:Bean 必須已在之前的 useBean 或其他方式放入作用域中。

四、完整實戰示例:用戶註冊表單

UserBean.java (符合 JavaBeans 規範)

package com.example.model;
public class UserBean implements java.io.Serializable {
    private String username;
    private String password;
    private String email;
    private int age;
    private java.util.Date regDate = new java.util.Date(); // 默認值
    // 標準 Getter/Setter (省略)...
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    // ... 其他屬性同理
}

register.jsp (接收表單提交)

<%@ page contentType="text/html;charset=UTF-8" %>
<html><body>
<h2>用戶註冊處理</h2>

<!-- 1. 聲明 Bean,請求範圍,自動創建 -->
<jsp:useBean id="user" class="com.example.model.UserBean" scope="request">
    <!-- 2. 自動將所有請求參數注入 Bean (username, password, email, age) -->
    <jsp:setProperty name="user" property="*" />
</jsp:useBean>

<!-- 3. 顯式設置默認/固定值 (註冊時間由 Bean 構造器默認,此處演示 value 用法) -->
<jsp:setProperty name="user" property="status" value="pending" />

<h3>註冊信息確認</h3>
<table border="1">
    <tr><th>字段</th><th>值</th></tr>
    <tr><td>用戶名</td><td><jsp:getProperty name="user" property="username" /></td></tr>
    <tr><td>郵箱</td><td><jsp:getProperty name="user" property="email" /></td></tr>
    <tr><td>年齡</td><td><jsp:getProperty name="user" property="age" /></td></tr>
    <tr><td>註冊時間</td><td><jsp:getProperty name="user" property="regDate" /></td></tr>
    <tr><td>狀態</td><td><jsp:getProperty name="user" property="status" /></td></tr>
</table>

<%-- 後續可將 user 對象傳遞給 Service/DAO 持久化 --%>
</body></html>

register.html (提交表單)

<form action="register.jsp" method="post">
    用戶名: <input name="username" /><br/>
    密碼: <input type="password" name="password" /><br/>
    郵箱: <input name="email" /><br/>
    年齡: <input name="age" /><br/>
    <input type="submit" value="註冊" />
</form>

五、進階主題與避坑指南

主題關鍵點
作用域選擇 page 默認,僅頁面內;request 配合 <jsp:forward> 傳遞數據;session 用戶登錄狀態、購物車;application 全局配置、緩存數據。
類型轉換與 PropertyEditor 標準轉換:String -> 基本類型、String、Date (格式需匹配)。自定義類型需註冊 PropertyEditor (罕用)。
只讀屬性/無 Setter setProperty 會跳過無 Setter 的屬性 (不報錯)。getProperty 要求有 Getter。
EL 表達式替代 (JSP 2.0+) 現代首選:${user.username} 替代 <jsp:getProperty>;<c:set target="${user}" property="status" value="active"/> 替代 setProperty。更簡潔、支持巢狀屬性、空值安全。
線程安全 scope="request/page" 每請求一實例,線程安全。session/application 共享實例,Bean **必須線程安全** (無可變狀態或同步)。

總結

useBean/setProperty/getProperty 三劍合璧,構成了 JSP 早期「Model 1」架構的核心,實現了請求參數到 JavaBean 的自動綁定與頁面輸出。雖然現代開發推薦使用 EL + JSTL + MVC 框架,但理解這三個標簽的**作用域語義、自動類型轉換、生命週期管理**,對維護老項目、排查 Bean 未生效/屬性未注入/ClassCastException 等問題,仍具不可替代的價值。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved