论坛首页 Java企业应用论坛

webwork 2.2 中如何给Collection赋值

浏览 20576 次
该帖已经被评为精华帖
作者 正文
   发表时间:2006-01-05  
原本javaeye有这么一篇帖子“在WebWork2 Action中如何自动设置Array、List、Map”,是moxie大哥写的。
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的集中基本访问方式:#、%{}、${}

以上内容,错漏难免。因为今天终于可以偷闲,赶紧结绳记之。欢迎大家讨论更简便的方法。
   发表时间: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的理解有误,现在看来上面的代码多此一举了
0 请登录后投票
   发表时间: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看看问题出在哪里。
0 请登录后投票
   发表时间: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报错内容呀。
0 请登录后投票
   发表时间:2006-03-29  
问题应该出在你的ftl模版里面。你的模版中ww:property 只有name属性,而里面又写的是users[0]这样的形式。property默认value取name相同的值,但你写成users[0]形式后就需要指定value值了。返回的list里面的值就为null。
估计如此。
0 请登录后投票
   发表时间: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
0 请登录后投票
   发表时间:2006-04-04  
建议xfv5k遇到null的问题调试就好了,看看是不是传进来的时候就是空的还是后面哪个地方搞错了,从parameterInterecpter一直跟到hibernate里面肯定能找到原因。
0 请登录后投票
   发表时间:2006-04-05  
我调整了一下xfv5k的代码,使之可以在webwork的quickstart 里直接运行。
解压到webwork 的webapp目录下。
然后用
%java_home%\bin\java -jar webwork-2.2.2.jar quickstart:dztc
即可执行。
0 请登录后投票
   发表时间: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,可以把玩一下。
0 请登录后投票
   发表时间:2006-04-05  
建议尽量把发布的例子做成quickstart模式的。
(如果想保持不一样的目录结构,编个好点的xml配置)

我刚改了可以用jettyplus支持jndi的了 。
:)

打算以后不用tomcat调试,直接拿quickstart调试了。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics