Struts 2 的通配符映射(Wildcard Mapping)能大幅減少 struts.xml 設定量,但預設不支援 Action 名稱含斜線(/),且驗證檔命名規則與斜線衝突。本文記錄從啟用通配符、解決斜線限制、到修正驗證檔載入的完整踩坑與修正過程。
在 struts.xml 定義通配符 Action:
<package name="alliance" namespace="/alliance" extends="struts-default">
<action name="*/*" class="cn.zeroall.cow.web.alliance.action.{1}Action" method="{2}">
<result name="target" type="velocity">/templates/alliance/{1}/${target}.vm</result>
<result name="success" type="velocity">/templates/alliance/{1}/{2}.vm</result>
<result name="input" type="velocity">/templates/alliance/{1}/{2}.vm</result>
<result name="fail" type="velocity">/templates/common/error.vm</result>
</action>
</package>
{1} 對應第一個 *(Action 類別前綴),{2} 對應第二個 *(方法名)。
預設 Struts 禁止 Action 名稱含 /,需在 struts.properties 開啟:
struts.enable.SlashesInActionNames = true
官方註釋說明:true 時允許斜線,支援 */ * 模式匹配 /foo/edit、/foo/save 等 URL。
Struts 2 慣例:驗證檔命名為 ActionName-actionName-validation.xml。對於 AlliedMemberAction/doRegister,預期檔名:
cn/zeroall/cow/web/alliance/action/AlliedMemberAction-AlliedMember/doRegister-validation.xml
斜線非合法檔名字元,導致驗證檔無法載入。
追蹤至 XWork AnnotationActionValidatorManager.buildAliasValidatorConfigs:
private List<ValidatorConfig> buildAliasValidatorConfigs(Class aClass, String context, boolean checkFile) {
String fileName = aClass.getName().replace('.', '/') + "-" + context + VALIDATION_CONFIG_SUFFIX;
return loadFile(fileName, aClass, checkFile);
}
context 即 Action 映射中的 URL 表達式(含斜線)。
修改源碼(或繼承覆寫):
String fileName = aClass.getName().replace('.', '/') + "-" + context.replace("/", "-") + VALIDATION_CONFIG_SUFFIX;
驗證檔實際命名變為:
AlliedMemberAction-AlliedMember-doRegister-validation.xml
符合檔案系統命名規範,驗證功能恢復正常。
*/ * 模式:改用 *-*(如 AlliedMember-doRegister),原生相容驗證檔命名@Validations 註解完全繞過檔案命名問題Struts 2 通配符映射強大但有陷阱:struts.enable.SlashesInActionNames=true 是啟用鑰匙;驗證檔命名衝突需源碼層面修正或改用替代模式。建議新專案優先考慮註解驗證或 RESTful 風格映射(actionName/methodName),避開此類相容性問題。