Struts2 <s:doubleselect> 專為「省市聯動」、「分類子分類」等雙層級下拉場景設計。核心原理:
list 綁定主選單集合doubleList 為 OGNL 表達式,動態根據第一層選中值 (top) 解析子選單onchange 事件重載子選單<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<package name="default" namespace="/" extends="struts-default">
<action name="doubleselectTag" class="com.struts.ui.action.DoubleSelectTagAction">
<result name="success">/doubleSelectTag.jsp</result>
</action>
</package>
// Province.java
public class Province {
private int id;
private String name;
// 建構子、getter/setter 略
}
// City.java
public class City {
private int id;
private String name;
// 建構子、getter/setter 略
}
public class DoubleSelectTagAction extends ActionSupport {
private List provinces; // 第一層資料源
private Map> cityMap; // 以 provinceId 為 key 的城市映射
public DoubleSelectTagAction() {
// 初始化省份
provinces = Arrays.asList(
new Province(1, "四川省"),
new Province(2, "山東省"),
new Province(3, "湖南省"),
new Province(4, "廣東省")
);
// 初始化城市映射
cityMap = new HashMap<>();
cityMap.put(1, Arrays.asList(new City(1, "成都市"), new City(2, "綿陽市")));
cityMap.put(2, Arrays.asList(new City(1, "濟南市"), new City(2, "青島市")));
cityMap.put(3, Arrays.asList(new City(1, "長沙市"), new City(2, "郴州市")));
cityMap.put(4, Arrays.asList(new City(1, "廣州市"), new City(2, "深圳市")));
}
// getter 略
public List getProvinces() { return provinces; }
public Map> getCityMap() { return cityMap; }
@Override
public String execute() { return SUCCESS; }
}
<%@ taglib uri="/struts-tags" prefix="s" %>
<s:form action="doubleselectTag">
<s:doubleselect
label="請選擇所在省市"
name="province" // 表單提交參數名:省份
list="provinces" // Action 中第一層集合屬性名
listKey="id" // Province 的 value 屬性
listValue="name" // Province 的 label 屬性
doubleName="city" // 表單提交參數名:城市
doubleList="cityMap.get(top.id)" // OGNL:根據當前省份 id 取城市列表
doubleListKey="id" // City 的 value 屬性
doubleListValue="name" // City 的 label 屬性
headerValue="----請選擇----" // 預設提示選項
emptyOption="true" // 允許空選項
/>
</s:form>
| 屬性 | 對應對象 | 說明 |
|---|---|---|
| list | Action.provinces | 第一層集合名稱 |
| listKey | Province.id | 第一層提交值 |
| listValue | Province.name | 第一層顯示文字 |
| doubleList | cityMap.get(top.id) | OGNL 表達式,top 為當前選中省份對象 |
| doubleListKey | City.id | 第二層提交值 |
| doubleListValue | City.name | 第二層顯示文字 |
| doubleName | city | 第二層表單參數名 |
若 cityMap 定義為 Map,則:
doubleList="cityMap.get(top)" // 直接用省份對象作 key
doubleListKey="id"
doubleListValue="name"
此時 top 直接是 Province 實例,無需 .id。

選擇「四川省」→ 第二層自動載入「成都市、綿陽市」;切換「廣東省」→ 即時更新為「廣州市、深圳市」。
top.id 與 listKey 型別一致(皆為 Integer)pageEncoding="UTF-8"、Tomcat URIEncoding="UTF-8"private Integer province; private Integer city; 對應 name/doubleName