给出例子代码
public class TestAction{ private List users; ////// getter setter } .... public class User{ private String username; ////getter setter }
在以上代码中,假设users集合装的是User类实例,则在于TestAction同包下建立一个TestAction-conversion.properties文件:
Element_users = com.xxxx.User(早期用Collection_)
页面上输入用户名如下脚本
<input name="users[0].username"/>
假设User用户有属于多个组group,那User变为
public class User{ private String username; private List groups; ////getter setter }
groups中存放的是com.yyy.Group类实例
public class Group{ private String gname; ////getter setter }
在于User同包下,建立User-conversion.properties:
Element_groups= com.yyy.Group
页面上输入组名如下
<input name=users[0][0].gname />
struts2或webwork给我们提供了以上支持,若是想明确集合中的对象,就在变量所属的类的同包下建立对应的***-conversion.properties,在文件中指定Element_xxx即可
假设有需求是集合中的元素也是集合,那struts2或webwork是不支持的,为了解决这个问题,首先重写XworkListPropertyAccessor
public class XWorkListPropertyAccessor extends ListPropertyAccessor { public XWorkListPropertyAccessor() { _sAcc = new XWorkCollectionPropertyAccessor(); } public Object getProperty(Map context, Object target, Object name) throws OgnlException { if(OgnlContextState.isGettingByKeyProperty(context) || name.equals("makeNew")) return _sAcc.getProperty(context, target, name); if(name instanceof String) return super.getProperty(context, target, name); OgnlContextState.updateCurrentPropertyPath(context, name); Class lastClass = (Class)context.get("last.bean.accessed"); String lastProperty = (String)context.get("last.property.accessed"); if((name instanceof Number) && OgnlContextState.isCreatingNullObjects(context) && XWorkConverter.getInstance().getObjectTypeDeterminer().shouldCreateIfNew(lastClass, lastProperty, target, null, true)) { List list = (List)target; int index = ((Number)name).intValue(); int listSize = list.size(); if(lastClass == null || lastProperty == null) return super.getProperty(context, target, name); Class beanClass = XWorkConverter.getInstance().getObjectTypeDeterminer().getElementClass(lastClass, lastProperty, name); if(listSize <= index) { Object result = null; for(int i = listSize; i < index; i++) list.add(null); try { list.add(index, result = ObjectFactory.getObjectFactory().buildBean(beanClass, context)); } catch(Exception exc) { throw new XworkException(exc); } return result; } if(list.get(index) == null) { Object result = null; try { list.set(index, result = ObjectFactory.getObjectFactory().buildBean(beanClass, context)); } catch(Exception exc) { throw new XworkException(exc); } return result; } } return super.getProperty(context, target, name); } //////////setProperty private XWorkCollectionPropertyAccessor _sAcc; }
注意在getProperty返回result时,判断result是否List类型
public class MoreXWorkListPropertyAccessor extends XWorkListPropertyAccessor { public Object getProperty(Map context, Object target, Object name) throws OgnlException { if(OgnlContextState.isGettingByKeyProperty(context) || name.equals("makeNew")) return _sAcc.getProperty(context, target, name); if(name instanceof String) return super.getProperty(context, target, name); OgnlContextState.updateCurrentPropertyPath(context, name); Class lastClass = (Class)context.get("last.bean.accessed"); String lastProperty = (String)context.get("last.property.accessed"); if((name instanceof Number) && OgnlContextState.isCreatingNullObjects(context) && XWorkConverter.getInstance().getObjectTypeDeterminer().shouldCreateIfNew(lastClass, lastProperty, target, null, true)) { List list = (List)target; int index = ((Number)name).intValue(); int listSize = list.size(); if(lastClass == null || lastProperty == null) return super.getProperty(context, target, name); Class beanClass = XWorkConverter.getInstance().getObjectTypeDeterminer().getElementClass(lastClass, lastProperty, name); if(listSize <= index) { Object result = null; for(int i = listSize; i < index; i++) list.add(null); try { list.add(index, result = ObjectFactory.getObjectFactory().buildBean(beanClass, context)); } catch(Exception exc) { throw new XworkException(exc); } if(result instanceof List){ OgnlContextState.setLastBeanPropertyAccessed(context,lastProperty+"_i"); } return result; } if(list.get(index) == null) { Object result = null; try { list.set(index, result = ObjectFactory.getObjectFactory().buildBean(beanClass, context)); } catch(Exception exc) { throw new XworkException(exc); } if(result instanceof List){ OgnlContextState.setLastBeanPropertyAccessed(context,lastProperty+"_i"); } return result; } } return super.getProperty(context, target, name); // 单例 instance = new MoreXWorkListPropertyAccessor(); private MoreXWorkListPropertyAccessor{} public MoreXWorkListPropertyAccessor getInstance(){return instance;} }
编写拦截器,设置MoreXWorkListPropertyAccessor;拦截器一定要配置在static-params之前
public class MoreDimensesSupportInterceptor extends AroundInterceptor{ public void before(ActionInvocation invocation)throws Exception{ OgnlRuntime.setPropertyAccessor(List.class,MoreXWorkListPropertyAccessor.getInstance()); } }
现在只需在TestAction.properties中指定
Element_users=java.util.ArrayList //二维集合配置
Element_users_i=com.xxx.User //二维集合配置
Element_users=java.util.ArrayList //三维集合配置
Element_users_i=java.util.ArrayList //三维集合配置
Element_users_i_i=com.xxx.User //三维集合配置