给出例子代码
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 //三维集合配置