OGNL是否支持List<Map<String,String>>类型?Struts2参数绑定问题咨询
问题原因分析
第一个报错(Map接口实例化失败)
你遇到的第一个报错不是OGNL不支持将Map存入List,核心原因是Map是接口类型,OGNL执行参数绑定需要为List的索引位置实例化元素对象时,无法通过接口创建实例,因此抛出找不到匹配构造方法的异常。
第二个报错(缺少INPUT视图配置)
替换为HashMap具体实现类后,出现No result defined for action and result input的原因是:Struts2默认拦截器栈包含类型转换、参数校验逻辑,只要绑定过程中出现任何错误(包括残留的绑定错误、校验规则触发),都会自动返回INPUT逻辑视图,你的Action注解中仅配置了SUCCESS视图,没有配置INPUT对应的返回路径,因此触发配置异常。
正确实现方案
1. Action代码调整
- 集合泛型使用具体的
HashMap实现类 - 补充
INPUT视图配置 - 可提前初始化List避免低版本Struts2扩容异常(可选)
示例修改后的核心代码:
// 字段定义使用具体HashMap实现类 private List<HashMap<String, String>> datasHM = new ArrayList<HashMap<String,String>>(); // 补充INPUT结果配置 @Action(value = "ognl-test", results = { @Result(name = SUCCESS, type = "dispatcher", location = "ognlTest.jsp"), @Result(name = INPUT, type = "dispatcher", location = "ognlTest.jsp") }) public String ognlTest() throws Exception { // 打印datasHM即可验证绑定结果 System.out.println(datasHM); return SUCCESS; }
2. JSP表达式调整
将输入框的name属性对应到使用HashMap的字段上即可,OGNL表达式写法不需要修改:
<s:textfield name="datasHM[0].testKey" ></s:textfield> <s:textfield name="datasHM[1].testKey" ></s:textfield> <s:textfield name="datasHM[2].testKey" ></s:textfield>
提交后即可自动完成绑定:List对应索引位置会自动创建HashMap实例,输入的值会自动存入key为testKey的键值对中。
可选扩展:保持List
如果你需要保持泛型为Map接口不修改,可以自定义Struts2类型转换器,全局指定Map接口的默认实现类为HashMap,这样不需要修改现有泛型定义也可以完成绑定。
内容的提问来源于stack exchange,提问作者DanielHuang
相关产品推荐
相关产品推荐

