该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2006-01-05
http://forum.iteye.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的集中基本访问方式:#、%{}、${} 以上内容,错漏难免。因为今天终于可以偷闲,赶紧结绳记之。欢迎大家讨论更简便的方法。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2006-01-05
我觉得XWorkList, XWorkMap还是很有用的,挺好的设计,其实没有必要deprecated。像现在的做法也还是有不足之处,只支持第一级Collection,对多层次好像还是要用老的办法,或者说也可以我还没看到。
我多数使用ModelDriven,一般就是一个model操作,用到Collection的地方那就是第二层之后了,还是得用XWorkList,model不是简单的new出来的,而是是用工厂产生XWork化的model,例如。 public class UserXWorkFactory { public static User getInstance(); { User user = new User();; user.setEmails(new XWorkList(UserEmail.class););; return user; } } 这样用起来就比较方便了。 ------ 补充:原来对converter的理解有误,现在看来上面的代码多此一举了 |
|
返回顶楼 | |
发表时间:2006-03-06
xfv5k 写道 楼主,我按你这个贴子搞半天也没成功.
按你设计的那个表单,提交后,action得不到值.报错如下: java.lang.IllegalArgumentException: attempt to create saveOrUpdate event with null entity 楼主你能不能搞好了,传个实例上来,方便学习. 这个。问题应该不出在conversion的部分吧,可能你的代码有问题。很多朋友都搞定啦,现在Webwork wiki介绍的也满详尽。除了给Action设置conversion,还可以给pojo设置conversion呢。 http://www.blogjava.net/iamtin/archive/2006/02/16/31099.html 你可以把你的代码法上来,我们帮你看看问题出在哪里。null应该是ognl没有正确赋值,你可以打开debug看看问题出在哪里。 |
|
返回顶楼 | |
发表时间:2006-03-10
你用的Webwork什么版本?是2.2 or 2.2.1?
还有你后面的页面有一个freemarker一个jsp版本是啥意思?没有xwork不知道你的action的流程呀。如果freemarker那个是post的页面的话我觉得你可以把它实际渲染后的html文件的源码贴过来,那样就可以判断问题出在哪里了(是输出格式有错,还是post后ognl set有错)。 你可以把log4j的com.opensymphony=debug,这样跟踪一下ognl报错内容呀。 |
|
返回顶楼 | |
发表时间:2006-03-29
问题应该出在你的ftl模版里面。你的模版中ww:property 只有name属性,而里面又写的是users[0]这样的形式。property默认value取name相同的值,但你写成users[0]形式后就需要指定value值了。返回的list里面的值就为null。
估计如此。 |
|
返回顶楼 | |
发表时间:2006-04-04
xfv5k 写道 Tin 写道 问题应该出在你的ftl模版里面。你的模版中ww:property 只有name属性,而里面又写的是users[0]这样的形式。property默认value取name相同的值,但你写成users[0]形式后就需要指定value值了。返回的list里面的值就为null。
估计如此。 我搞成了,但不是根据你说的那个方法。 参考了这个贴子,http://forum.iteye.com/viewtopic.php?t=15709 webwork2.2.2自带例子showcase 的PersonManager Sample 是最好的例子。 我又下载了你新的dztc.rar那个包,看了半天,没明白你怎么解决了问题,也不知道你原先问题出在哪里,我倒是一头雾水。 这段代码什么意思? public class TestAction extends ActionSupport{ private List users=new ArrayList();; private User user; public TestAction();{ for(int i=0;i<2;i++); users.add(new User(););; } public void setUsers(List users);{ this.users=users; } public List getUsers();{ return users; } public String execute();{ /* for(Iterator it=users.iterator();;it.hasNext();;);{ user=(User);it.next();; users.add(user);; } */ return SUCCESS; } } 你不是根本就没从页面读取数据么? 希望你把解决问题的细节写一写,对大家都很有帮助。:D |
|
返回顶楼 | |
发表时间:2006-04-04
建议xfv5k遇到null的问题调试就好了,看看是不是传进来的时候就是空的还是后面哪个地方搞错了,从parameterInterecpter一直跟到hibernate里面肯定能找到原因。
|
|
返回顶楼 | |
发表时间:2006-04-05
我调整了一下xfv5k的代码,使之可以在webwork的quickstart 里直接运行。
解压到webwork 的webapp目录下。 然后用 %java_home%\bin\java -jar webwork-2.2.2.jar quickstart:dztc 即可执行。 |
|
返回顶楼 | |
发表时间:2006-04-05
xfv5k 写道 Tin 写道
TIN我那个包解压后,lib目录下加载必要的包(如:webwork2.2任何一个例子lib目录下的包都可以。),就可以布署成功。然后访问http://localhost:8080/dztc/tmd/add!input.action就可以感受到了。我觉得你没有试一下我提供的例子。 没什么细节,我也搞不懂,这个贴子说得比我明白http://forum.iteye.com/viewtopic.php?t=15709 我算明白了。其实本意这个conversion是为了给Collection赋值。而你的问题是录入的界面load时出错,而不是post出错。其实这样的代码还是相当不好的。 可以重构到prepare()方法,使用prepareInteceptor。 还有,新的xwork-tiger已经支持泛型Collection,就不用写conversion文件了,很方便自己写scaffold,可以把玩一下。 |
|
返回顶楼 | |
发表时间:2006-04-05
建议尽量把发布的例子做成quickstart模式的。
(如果想保持不一样的目录结构,编个好点的xml配置) 我刚改了可以用jettyplus支持jndi的了 。 :) 打算以后不用tomcat调试,直接拿quickstart调试了。 |
|
返回顶楼 | |