Struts2如何使用Struts1风格的索引属性Getter/Setter方法?
Struts2中如何使用Struts1风格的索引属性Getter/Setter方法
首先得明确:Struts2默认并不直接支持Struts1这种带索引参数的getter/setter写法,毕竟它依赖OGNL表达式处理属性,集合的访问逻辑和Struts1有不小差异。不过我们有两种思路来实现类似需求,一种是适配Struts2原生的最佳实践,另一种是自定义转换器模拟Struts1的行为。
一、优先用Struts2原生的集合处理方式(推荐)
如果不是非要严格照搬Struts1的方法签名,Struts2自带的集合处理其实更简洁,而且完全兼容你现有的页面代码:
- 在Action/模型类里定义集合属性
直接声明一个List<String>(或者其他集合类型),并提供标准的getter/setter:private List<String> myIdxProp = new ArrayList<>(); public List<String> getMyIdxProp() { return myIdxProp; } public void setMyIdxProp(List<String> myIdxProp) { this.myIdxProp = myIdxProp; } - 页面代码完全不用改
你原来的<input type="text" name="myIdxProp[1]" value="foo" />可以直接用,OGNL会自动把对应索引的值填充到集合里,取值的时候也可以通过myIdxProp.get(index)直接获取,非常方便。
这种方式是Struts2官方推荐的,代码更清晰,也符合框架的设计逻辑。
二、硬要模拟Struts1风格的带索引参数方法?可以自定义类型转换器
如果因为历史代码兼容等原因,必须保留Struts1那种带int index参数的getter/setter,那得自定义类型转换器来拦截属性赋值:
- 写一个自定义类型转换器
我们需要实现Struts2的TypeConverter接口,手动解析页面传递的索引参数,然后调用对应的setter方法:import com.opensymphony.xwork2.conversion.TypeConverter; import java.util.Map; import java.lang.reflect.Method; public class IndexedPropertyConverter implements TypeConverter { @Override public Object convertValue(Map<String, Object> context, Object target, Member member, String propertyName, Object value, Class toType) { // 只处理我们关心的myIdxProp属性 if (target != null && "myIdxProp".equals(propertyName) && value instanceof String[]) { String[] paramValues = (String[]) value; for (String param : paramValues) { // 简单解析索引,比如从"myIdxProp[1]"里提取出1 int startIdx = param.indexOf("[") + 1; int endIdx = param.indexOf("]"); int index = Integer.parseInt(param.substring(startIdx, endIdx)); // 提取对应的值(实际场景可能需要更严谨的参数解析,比如处理POST请求的参数结构) String val = param.split("=")[1]; try { // 反射调用目标对象的setMyIdxProp(int, String)方法 Method setter = target.getClass().getMethod("setMyIdxProp", int.class, String.class); setter.invoke(target, index, val); } catch (Exception e) { e.printStackTrace(); } } } return null; // 我们已经手动处理了赋值,返回null即可 } } - 配置转换器
在Action所在的包下创建xwork-conversion.properties文件,指定属性对应的转换器:
如果想全局生效,也可以在# 替换成你的Action全类名和属性名 com.yourpackage.YourAction.myIdxProp=com.yourpackage.IndexedPropertyConvertersrc/main/resources下创建全局的xwork-conversion.properties,配置对应的集合类型转换器。 - 保留Struts1风格的方法
你的Action/模型类里依然保留原来的方法:public void setMyIdxProp(int index, String value){ // 这里写你的业务逻辑 } public String getMyIdxProp(int index) { String retVal = ""; // 从数据源获取对应索引的值 return retVal; }
不过这种方式需要自己处理参数解析,复杂度较高,容易踩坑,除非有特殊的兼容需求,不然还是优先用第一种原生方式。
内容的提问来源于stack exchange,提问作者Tarator
相关产品推荐
相关产品推荐

