Tin's Blog

You are coming a long way, baby~Thinking, feeling, memory...

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  128 随笔 :: 0 文章 :: 221 评论 :: 0 Trackbacks

原本javaeye有这么一篇帖子“在WebWork2 Action中如何自动设置Array、List、Map”,是moxie大哥写的。
http://forum.javaeye.com/viewtopic.php?t=8770

但是已经是2004年11月的文章了,在webwork 2.2 b4中,XWorkList和XWorkMap已经是deprecated状态了,当时我就一头雾水,也没找到什么好的线索。
去java.net下载了XWork的最新代码,看到了其中的注释,说这个工作已经可以自动完成了。
又几经周折,才算搞明白先在如何让List、Map等工作起来,给予2.2 b4和b5工作正常:

下面简单介绍一下:
1、如果要将值映射到pojo的collection,则需要使用conversion功能。
如我又一个Action,叫testAction:

public class testAction extends ActionSupport 
        
private Collection smoeAttrs = null;//(使用webwork自动负值,应有对应getter和setter) 
        private IDeptJgzTjkEcoAttDAO ecoAttDAO = null;//(改DAO使用Spring注入,应有相应setter) 

            
public String execute() throws Exception 
                
if (log.isDebugEnabled()) 
                        log.debug(
"performing execute() method!"); 
                }
 
                
                
//持久化collection里面的pojo 
                for (Iterator iterator = smoeAttrs.iterator(); iterator.hasNext();) 
                            SomeAttr someAttr 
= (SomeAttr) iterator.next(); 
                            ecoAttDAO.saveOrUpdate(someAttr, someAttr.getId()); 
                }
 
                
                       
return Action.SUCCESS; 
            }
 
}

对应一个pojo:

package org.tin.test; 

public class SomeAttr implements Serializable 

        
/** The composite primary key value. */ 
        
private java.lang.Long id; 

        
private java.lang.Float fild1; 
        
private java.lang.String fild2; 
        
private java.util.Date fild3; 

        
/* 
                
                对应的getter和setter 
        
*/
 
}

可以看到,上面的Action声明的时候没有任何涉及到XWorkList的地方(moxie介绍的那种风格),也就是说现在webwork并不知道Collection里面放的pojo的类型。这就是Webwork目前的高明之处,这样的代码非常干净。但是如果要自动设定Collection的值,访问到这些Pojo,则一定要知道Pojo的类型,Webwork如何做呢?
通过-conversion配置。
需要在对应该才那个testAction.java的相同目录写一个testAction-conversion.properties文件(格式就是Action名字+“-conversion.properties”)。
文件里面注明:
Element_someAttrs = org.tin.test.SomeAttr (以前版本曾经用过Collection、Map分开,但是现在不管什么类型,都用Element)
格式就是“Element_”+Action中Collection的名字+“=”+你的pojo的完整类名

如此配置后,自动设置值的时候就可以知道你的pojo的类型了,很干净。

下面一小段由于我接触Webwork不久,所以是个很初级的经验,如果需要则自取:
回忆moxie帖子中的重要的部分,在post到相应action的页面的form中,input要遵循这样的命名:
对应刚才所说的那个pojo:

<form> 
        
<input  name="someAttrs[0].fild1" value="45555.6" id="xxx11" /> 
        
<input  name="someAttrs[0].fild2" value="test" id="xxx12" /> 
        
<input  name="someAttrs[0].fild3" value="2006-01-05" id="xxx13" /> 
        
<input  name="someAttrs[1].fild1" value="45555.6" id="xxx21" /> 
        
<input  name="someAttrs[1].fild2" value="test" id="xxx22" /> 
        
<input  name="someAttrs[1].fild3" value="2006-01-05" id="xxx23" /> 
        
<input  name="someAttrs[2].fild1" value="45555.6" id="xxx31" /> 
        
<input  name="someAttrs[2].fild2" value="test" id="xxx32" /> 
        
<input  name="someAttrs[2].fild3" value="2006-01-05" id="xxx33" /> 
</form>

如何输出?很简单,在列表页中: 

<ww:iterator value="someAttrs" status="someAttrsIter"> 
<tr> 
        
<td> 
                
<ww:hidden name="someAttrs[%{#someAttrsIter.index}].id" value="%{id}"/> 
                
<ww:textfield name="someAttrs[%{#someAttrsIter.index}].fild1" value="%{fild1}"/></td> 
        
<td><ww:textfield name="someAttrs[%{#someAttrsIter.index}].fild2 value="%{fild2}"/></td> 
        
<td><ww:textfield name="someAttrs[%{#someAttrsIter.index}].fild3" value="%{fild3}"/></td> 
</tr> 
</ww:iterator>


即可以,因为iteratror这个tag支持iteratroStatus这个东西,用它可以获取index、isOdd等信息,很方便。

配合

<action name="saveAction" class="testAction"> 
        
<result name="success" type="redirect">/loadByInf.action?id=${someAttrOwner.id}</result> 
</action>

则很容易的实现对Collection的CRUD。正好用到了ONGL的集中基本访问方式:#、%{}、${}

以上内容,错漏难免。因为今天终于可以偷闲,赶紧结绳记之。欢迎大家讨论更简便的方法。

 

posted on 2006-02-16 21:19 Tin 阅读(3073) 评论(9)  编辑  收藏 所属分类: Webwork相关

评论

# re: webwork 2.2 中如何给Collection赋值 2006-02-16 23:44 李李
给你补充一点,-conversion.properties设定不局限于webwork action,支持任意pojo,意味着可以支持无限层次的Collection自动赋值,如:
root.one[0].two[0].three[0]
root.one[0].two[0].three[1]
...
root.one[n].two[n].three[n]
  回复  更多评论
  

# re: webwork 2.2 中如何给Collection赋值 2006-02-17 08:38 Tin
@李李
谢谢。对pojo的conversion.properties应该存放在哪个目录对应呢?
如果pojo和action都支持conversion真得很方便。  回复  更多评论
  

# re: webwork 2.2 中如何给Collection赋值 2006-02-17 10:44 李李
pojo的package下。
classname-conversion.properties  回复  更多评论
  

# re: webwork 2.2 中如何给Collection赋值 2006-08-07 12:04 lxl
@李李
pojo的package下。
classname-conversion.properties
————————————————
那么里面的内容如何写呢,我要访问action.first.items里面的bean,可是不知道该怎么写配置文件  回复  更多评论
  

# re: webwork 2.2 中如何给Collection赋值 2006-09-09 16:48 coolfish
你这个例子用的拦截器是哪个?defaultStack?我的怎么必须用到workflow那个拦截器才行啊?
  回复  更多评论
  

# re: webwork 2.2 中如何给Collection赋值 2006-09-09 16:52 coolfish
还有我试了试: user---->多个Address

然后页面里写 user.address[0].street

properties: 写Element_user.address = org.fish.ww2.model.Address

这样也没取到值?  回复  更多评论
  

# re: webwork 2.2 中如何给Collection赋值 2006-09-10 22:30 Tin
这个和拦截器没有关系,是XWork的内置功能。你可以看看Type Conversion的文档。如果不行你先看看你所使用的Webwork的版本,Element_xxx这个语法好像是从2.2.1开始支持的。  回复  更多评论
  

# re: webwork 2.2 中如何给Collection赋值 2006-09-11 08:52 coolfish007
我用的是2.2.2这个版本,如果不用Elemnt_时webwork会在log里警告老的用法过时.现在页面的对象可以填充到collection中了,但就是从collection中第二个对象开始一些field的值为null(而页面是写了值的)比如页面上:

<input name="fruites[0].nameD" value="apple" id="c1">Apple
<input name="fruites[0].produceArea" value="CN" id="c12">Apple
<input name="friutes[1].nameD" value="orangle" id="c2">Orangle
<input name="fruites[1].produceArea" value="USA" id="c22">Apple
<input name="friutes[2].nameD" value="banana" id="c3">Orangle
<input name="fruites[2].produceArea" value="UK" id="c32">Apple


Action中引用的private List fruites;
List里除了第一个对象的name正确赋值之外,剩下两个都是null,而produceArea赋值正确. 真是好奇怪

还有,关于拦截器,如果我在xwork.xml只引用"param"时,list中什么都没有.  回复  更多评论
  

# re: webwork 2.2 中如何给Collection赋值 2006-09-11 09:48 coolfish007
现在可以了,我把页面上的<input ...>换成<ww:textfield label="%{getText('Apple')}" name="fruites[0].nameD" value="apple"/>这种就可以了,所有值都正确填充了.  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: