| 屬性 | 說明 | 對應 HTML |
list | 資料來源 (必須),支援 List/Map/Set/陣列 | <option> 群組 |
listKey | 選項 value 值對應的屬性/Key | value="..." |
listValue | 選項顯示文字對應的屬性/Value | 選項內容文字 |
name | 表單欄位名 (對應 Action 屬性) | name="..." |
headerKey/headerValue | 首行提示選項的 key/value | 第一個 <option> |
required | 前端驗證必填 | required |
三、Action 準備資料:ClientUserAction
public class ClientUserAction extends ActionSupport {
private List<Client> clients; // Client: id, clientId, clientName
private List<User> users; // User: userid, username
public String queryClientID() {
Map session = ActionContext.getContext().getSession();
String userid = (String) session.get("userid");
setUsers(DAOFactory.getEmployeeInstance().queryUidUserid());
setClients(DAOFactory.getClientInstance().queryByAll(userid));
return SUCCESS;
}
// getter/setter 略
}
四、JSP 頁面綁定範例
<s:form action="clientuser_changeClient" method="post">
<!-- 1. 單選下拉:客戶 ID -->
<s:select list="clients" name="clientuser.clientId"
listKey="clientId" listValue="clientId"
label="選擇你將要轉讓的客戶" required="true" />
<!-- 2. 單選下拉:受讓同事 -->
<s:select list="users" name="clientuser.userid"
listKey="userid" listValue="userid"
label="將要轉讓給同事" required="true" />
<!-- 3. 雙層聯動:第一層選客戶,第二層顯示該客戶相關資料 -->
<s:doubleselect list="clients" name="client.clientId"
listKey="clientId" listValue="clientId"
doubleName="client.clientName" doubleList="clients"
doubleListKey="clientName" doubleListValue="clientName" />
<!-- 4. 上下移動排序:所有客戶 ID -->
<s:updownselect label="All Clients ID" list="clients"
listKey="clientId" listValue="clientId"
headerKey="0" headerValue="--所有客戶編號--"
moveUpLabel="向上" moveDownLabel="向下" selectAllLabel="全選" />
<!-- 5. 上下移動排序:所有客戶名稱 -->
<s:updownselect label="All Clients Name" list="clients"
listKey="clientName" listValue="clientName"
headerKey="0" headerValue="--所有客戶姓名--" />
<s:submit value="確認轉讓" onclick="alert('轉讓後你就失去了該客戶');" />
</s:form>
五、listKey/listValue 映射規則詳解
| 資料來源類型 | listKey | listValue | 說明 |
| List<POJO> | POJO 屬性名 | POJO 屬性名 | OGNL 表達式存取屬性 |
| Set<POJO> | POJO 屬性名 | POJO 屬性名 | 同 List |
| Map<K, V> | Key | Value | 直接對應 Map 的鍵值 |
| List<String> | 不可指定 | 不可指定 | 字串本身既是 key 也是 value |
範例:Client 物件
public class Client {
private String clientId;
private String clientName;
// getter/setter
}
// JSP
<s:select list="clients" listKey="clientId" listValue="clientName" />
// 生成
<option value="C001">客戶一</option>
<option value="C002">客戶二</option>
六、<s:doubleselect> 雙層聯動深度解析
機制
- 第一層:
list + listKey/listValue
- 第二層:
doubleList 為 OGNL 表達式,top 代表第一層選中的物件
- 內部用 JavaScript 實現聯動
正確用法:Map 結構
// Action 準備 Map<String, List<Client>>
Map<String, List<Client>> clientMap = new HashMap<>();
clientMap.put("GROUP_A", groupAClients);
clientMap.put("GROUP_B", groupBClients);
// JSP
<s:doubleselect list="clientMap" name="group"
listKey="key" listValue="key"
doubleName="client" doubleList="clientMap[top.key]"
doubleListKey="clientId" doubleListValue="clientName" />
錯誤用法修正
原文中 doubleList="clients" 且 doubleListKey="clientName" 邏輯錯誤,應改為上述 Map 結構或:
<s:doubleselect list="clients" name="client.clientId"
listKey="clientId" listValue="clientId"
doubleName="client.clientName"
doubleList="top.clientDetails" // 假設 Client 有 clientDetails 屬性
doubleListKey="detailId" doubleListValue="detailName" />
七、<s:updownselect> 排序選擇
- 生成雙列表箱:可用項目 / 已選項目
- 支援上移/下移/全選按鈕 (可自訂標籤)
- 提交時
name 參數包含已選項目順序的值陣列
八、常見問題與解決
| 問題 | 原因 | 解決 |
| 下拉框顯示空白 | list 屬性為 null 或空集合 | Action 確保初始化、或加 headerKey/headerValue |
| 提交值為 null | name 屬性與 Action 屬性不匹配 | 檢查 name="clientuser.clientId" 對應 Action 的 clientuser.clientId |
| doubleselect 第二層不變 | doubleList 表達式錯誤、top 變數誤解 | 使用 Map 結構、或確保 doubleList 依賴 top 物件屬性 |
| updownselect 順序不保存 | 未正確接收陣列參數 | Action 屬性用 String[] 或 List<String> 接收 |
九、最佳實踐建議
- 資料來源統一命名:Action 中集合屬性名與 JSP
list 值一致
- POJO 實作 toString():除錯時方便查看物件內容
- 大量資料分頁/懶載入:避免一次載入數萬筆選項導致頁面巨大
- 主題切換:
theme="simple" 關閉預設表格佈局,自行控制 CSS
- 國際化:
headerValue="%{getText('please.select')}" 從資源檔取值
- 上一篇文章: EJB 2.0 有狀態 SessionBean 完整開發與部署實戰
- 下一篇文章: Spring 2.5 註解開發入門:@Service、@Autowired、@Qualifier 完整範例
Copyright ©
程式碼之家 All Rights Reserved