Struts 2 的 Ajax 支援建立在 Dojo 與 DWR 基礎之上,提供輸入驗證、表單提交、發布-訂閱事件模型、自動完成與 JSON 整合等功能。筆記記錄於 Struts 2.0.6/2.0.11 版本環境,實戰經驗分享。
dwr-1.1-beta-3.jar,正式環境建議升級至穩定版 1.1.4;若用 DWR 2.0 需充分測試<s:head theme="ajax"/> + <s:form theme="ajax" validate="true"><servlet>
<servlet-name>dwr</servlet-name>
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dwr</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN"
"https://www.getahead.ltd.uk/dwr/dwr10.dtd">
<dwr>
<allow>
<create javascript="validator" creator="new">
<param name="class" value="org.apache.struts2.validators.DWRValidator"/>
</create>
<convert match="com.opensymphony.xwork2.ValidationAwareSupport" converter="bean"/>
</allow>
<signatures>
<![CDATA[
import java.util.Map;
import org.apache.struts2.validators.DWRValidator;
DWRValidator.doPost(String, String, Map<String, String>);
]]>
</signatures>
</dwr>
關鍵點:Map<String,String> 寫法為 DWR 泛型解析器所需,不依賴 JDK 1.5 泛型特性,JVM 1.4 亦可運行。若集合元素皆為字串,可省略 signatures。
<s:head theme="ajax"/>
<s:form action="Login" method="post" theme="ajax" validate="true">
<s:textfield name="name" label="姓名"/>
<s:textfield name="pass" label="密碼"/>
<s:submit label="登入"/>
</s:form>
輸入框失去焦點(onblur)時自動發送 XMLHttpRequest 至伺服器驗證。缺少 <s:head theme="ajax"/> 雖能驗證但會報 dojo 未定義 錯誤且提示非紅色。
命名慣例同後端驗證:ActionName-validation.xml。Ajax 直接使用該檔案定義的規則。
將 xwork-2.0.1.jar 換成 2.0.4.jar 後,Ajax 驗證拋出 NoClassDefFoundError: ValidatorFactory。雖類別確實存在,但初始化失敗。暫時回退 2.0.1,後續再查明根因。
Ajax 驗證未通過時表單無法提交。但後端驗證不可省略,因前端值可被竄改繞過 onblur 事件。幸運的是兩者共用同一驗證規則檔,Ajax 後仍有一次可靠的後端驗證。
Struts 2 會強制產生 onblur="validate(this);",自行添加 onblur 也會被覆蓋。兩種解法:
theme="xhtml"(風格一致,因 ajax 擴展自 xhtml)<s:submit targets="show"/> 以 Ajax 方式提交,結果頁內容作為 <div id="show"> 的 innerHTML。targets 可指定多個 ID(逗號分隔)同時更新多處。
<s:submit executeScripts="true" targets="show"/> 可執行結果頁中的 JavaScript(VBScript 不執行)。結果頁應僅輸出所需資料片段,非完整 HTML。注意:結果頁含 <s:debug/> 時,JavaScript 可能不執行。
需求:輸入驗證用 Ajax,提交用傳統方式。關鍵在提交按鈕:<s:submit theme="xhtml"/> 覆寫表單繼承的 ajax 主題,風格不變卻以傳統方式提交。同理可解決「個別欄位不需 Ajax 驗證」問題。
Struts 2 基於 Dojo 實現 Pub-Sub 模型,允許鬆耦合的元件通訊。詳細理解與實戰範例將於後續補充。
告知 DWR DWRValidator.doPost 方法參數中 Map 集合的泛型類型,使 DWR 知道如何處理該參數。DWR 內建泛型解析器,不依賴 JDK 1.5。實際使用中,若 List/Map 元素類型(含 Map Key)皆為字串,可省略 signatures 配置。