JavaBean 是 JSP 開發核心元件,封裝資料與業務邏輯。掌握 Bean 規範、屬性存取標籤、作用域管理與實際應用模式,建構可維護的企業級應用。
符合以下條件的 Java 類別即為 JavaBean:
| 規範項目 | 要求 |
|---|---|
| 建構子 | 提供公用無參數建構子 |
| 序列化 | 實作 java.io.Serializable 介面 |
| 屬性存取 | 提供 getter/setter 方法 (可唯讀/唯寫) |
| 命名慣例 | getPropertyName() / setPropertyName() |
package com.example.model;
public class StudentsBean implements java.io.Serializable {
private String firstName = null;
private String lastName = null;
private int age = 0;
// 無參數建構子
public StudentsBean() { }
// Getter 方法
public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
public int getAge() { return age; }
// Setter 方法
public void setFirstName(String firstName) { this.firstName = firstName; }
public void setLastName(String lastName) { this.lastName = lastName; }
public void setAge(int age) { this.age = age; }
}
# 編譯
javac StudentsBean.java
# 部署至 Web 應用
# 目標路徑:WEB-INF/classes/com/example/model/StudentsBean.class

<jsp:useBean id="bean名稱"
scope="page|request|session|application"
class="完整類別名稱" />
<!-- 或包含主體進行初始化 -->
<jsp:useBean id="bean名稱" scope="session" class="com.example.StudentsBean">
<jsp:setProperty name="bean名稱" property="*" />
</jsp:useBean>
| scope 值 | 生命週期 | 共用範圍 |
|---|---|---|
| page | 單一頁面請求 | 僅當前頁面 (預設) |
| request | 單一 HTTP 請求 | 同請求轉發/包含的頁面 |
| session | 使用者 Session | 同使用者所有請求 |
| application | 應用程式存活期間 | 所有使用者、所有請求 |
<!-- 單一屬性設定 -->
<jsp:setProperty name="bean名稱" property="屬性名" value="值" />
<!-- 自動對應請求參數 (property="*") -->
<jsp:setProperty name="bean名稱" property="*" />
<!-- 指定參數名對應不同屬性 -->
<jsp:setProperty name="bean名稱" property="屬性名" param="請求參數名" />
<jsp:getProperty name="bean名稱" property="屬性名" />
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<html><body>
<jsp:useBean id="date" class="java.util.Date" />
<p>目前時間:<%= date %></p>
</body></html>
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<html><head><title>JavaBean 操作範例</title></head><body>
<jsp:useBean id="student" class="com.example.model.StudentsBean" scope="request">
<jsp:setProperty name="student" property="firstName" value="小強"/>
<jsp:setProperty name="student" property="lastName" value="王"/>
<jsp:setProperty name="student" property="age" value="20"/>
</jsp:useBean>
<p>學生名字:<jsp:getProperty name="student" property="firstName"/></p>
<p>學生姓氏:<jsp:getProperty name="student" property="lastName"/></p>
<p>學生年齡:<jsp:getProperty name="student" property="age"/></p>
</body></html>
學生名字:小強
學生姓氏:王
學生年齡:20
<html><body>
<form action="process.jsp" method="post">
名字:<input type="text" name="firstName" /><br/>
姓氏:<input type="text" name="lastName" /><br/>
年齡:<input type="number" name="age" /><br/>
<input type="submit" value="送出" />
</form>
</body></html>
<!-- process.jsp -->
<jsp:useBean id="student" class="com.example.model.StudentsBean" scope="request">
<jsp:setProperty name="student" property="*" />
</jsp:useBean>
<p>收到資料:${student.firstName} ${student.lastName}, ${student.age} 歲</p>
| 場景 | 建議 Scope | 理由 |
|---|---|---|
| 頁面暫存計算結果 | page | 請求結束即釋放,不佔記憶體 |
| 表單驗證錯誤回填 | request | 轉發至表單頁面共用 |
| 使用者登入資訊 | session | 跨請求保持登入狀態 |
| 系統設定、快取資料 | application | 全域共用、啟動載入 |
| 購物車 | session | 用戶專屬、跨頁面存取 |
public class RegisterFormBean implements Serializable {
private String username;
private String email;
private String password;
private String confirmPassword;
// getter/setter...
// 業務驗證方法
public boolean isValid() {
return username != null && email != null
&& password != null && password.equals(confirmPassword);
}
public List<String> getErrors() {
List<String> errors = new ArrayList<>();
if (username == null || username.trim().isEmpty())
errors.add("使用者名稱必填");
if (!email.contains("@")) errors.add("Email 格式錯誤");
if (password == null || password.length() < 6)
errors.add("密碼至少 6 碼");
if (!password.equals(confirmPassword))
errors.add("兩次密碼不一致");
return errors;
}
}
<jsp:useBean id="utils" class="com.example.util.StringUtils" scope="application" />
<p>格式化金額:${utils.formatCurrency(order.total)}</p>
<p>截斷文字:${utils.truncate(description, 100)}</p>
public class OrderVO implements Serializable {
private Long id;
private String orderNo;
private BigDecimal total;
private List<OrderItemVO> items;
private CustomerVO customer;
private Date createTime;
// getter/setter...
}
現代 JSP 推薦使用 EL 直接存取 Bean 屬性:
<jsp:useBean id="student" class="com.example.StudentsBean" scope="request">
<jsp:setProperty name="student" property="*" />
</jsp:useBean>
<!-- EL 取代 jsp:getProperty -->
<p>姓名:${student.firstName} ${student.lastName}</p>
<p>年齡:${student.age}</p>
<!-- EL 取代 jsp:setProperty (僅讀取) -->
<c:if test="${student.age >= 18}">
成年人
</c:if>
| 問題 | 原因 | 解決 |
|---|---|---|
| Bean 找不到類別 | class 路徑錯誤、未部署至 WEB-INF/classes | 檢查 package 名稱、編譯輸出路徑 |
| 屬性無法設定 | 缺少 setter、型別不符、property 名稱錯誤 | 確認 setter 存在、型別轉換、名稱大小寫 |
| 作用域不生效 | scope 拼錯、轉發未包含目標頁面 | 使用正確 scope、request 轉發而非 redirect |
| property="*" 不動作 | 請求參數名與屬性名不符、型別轉換失敗 | 參數名=屬性名、提供 String→目標型別轉換 |
| Thread Safety 問題 | application/session scope Bean 非執行緒安全 | 使用同步機制、ThreadLocal、無狀態設計 |