关于Struts 2的类型转换

一个业务需求是:
栏目与模板的关系是多对一的关系,增加栏目时,需要在页面中选择栏目所使用的模板。
栏目的PO:
public class Testcolumn implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String colname;
private Testtemplate temp;
…………
}
模板的PO:
public class Testtemplate implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String tempname;
private String tempbody;
private Set columns;
…………
}

增加栏目的JSP包含如下代码:





/s:form

在后台的Action方法中,通过前台获取到了模板对象的id,那么我要么new一个带id属性的模板对象给栏目对象的这个模板属性赋值,要么使用Spring的BeanUtils使栏目的temp属性赋值。
Struts 2中能否直接对栏目的temp属性进行赋值。

我尝试着将JSP页面中的s:select修改为:

但出现后台错误。
请问大家这样的问题你们都是如何解决的?Struts 2是否具备这样的功能?
[b]问题补充:[/b]
首先先谢谢各位的帮助,我在补充一下我的问题。

PO还是之前那样。
栏目的PO对象中关于模板的属性是一个模板对象,两者是多对一的关系。
当在页面上需要增加栏目(Testcolumn)时,首先点击增加按钮后,首先先进入Action的一个叫addjump(),方法从数据库中将所有的模板(Testtemplate)获取并封装到一个List中(public List templist;)
之后跳转到新增的JSP页面。
在页面中,通过填写栏目名称,并选择栏目所使用的模板之后,提交便可增加栏目对象。

这里说一下再Struts1时我的JSP页面。



[color=red]首先明确说明,这种情况下,Struts 2中不能直接对栏目的temp属性进行赋值。[/color]

原因如下:
[quote] [/quote]

如果你的select中[color=red]listKey="id"[/color],listKey的值为id,那你的name值必须是column.temp.id;这样当后台接收到这个id的时候,会利用反射机制自动调用你的模板类中的setId()方法,从而为模板的id赋值。(最重要的一点就是,当点击增加按钮时,对于这个select,传递的是listKey指定的值,其他不会传递任何和这个select有关的值)

至于你说的,如果改为:
[quote] [/quote]

name="column.temp",当后台接收到的时,会自动查找是否有setTemp()方法,查找到没有,就是有也会出现异常,以为类型不对,不信,你可以试试,你传递的是字符串类型,而后台需要赋值的是模板类型,当然会出现异常了。

所以通用的方法是:
[code="java"]import com.opensymphony.xwork2.ActionSupport;

public class OperationAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private Testcolumn column;

public Testcolumn getColumn() {
    return column;
}

public void setColumn(Testcolumn column) {
    this.column = column;
}

public String execute() {
    System.out.println("栏目的名称:" + column.getColname());
    System.out.println("栏目描述:" + column.getColdesc());
    Testtemplate template = new Testtemplate();
    template.setId(column.getTemp().getId());
    column.setTemp(template);
    //save(column)//保存操作,或调用DAO
    return SUCCESS;
}

}[/code]

上面我只是给你举了一个例子。

你这可能是没把s:select 标签使用正确吧,应该是可以的

http://icemoon.iteye.com/blog/108592

自己做类型转换,可以参考http://struts.apache.org/2.0.14/docs/type-conversion.html

在这个例子中Struts2根本不可能知道你的业务逻辑也就不可能将template对象传给Action,你需要自己实现TyperConverter接口

Struts支持这种对象的嵌套,但是要提供默认的构造函数或者已经初始化。

如果这样的话Testcolumn 中的TestTemplate对象只有一个id值。

不知道满足不满足LZ的需求。

要不LZ再具体说一下自己的需求,这个问题不难。

[size=large][color=red]楼主,你好好看看我我回答吧,你如果明白Struts2传递参数的原理,以及select标签的功能,可能就不会再问了。上面我已经给你分析很清楚了。

另外你在好好看看,我给你讲的select标签传值的原理吧。[/color][/size]

还是没有看懂LZ想表达什么意思。

如果页面中只有column.temp.id那么在Action中的column的template对象只有id值,不会有别的值,这个Struts2可以帮你搞定。

listKey="id"传的是templist列表中各个模板对象的id值,
我想能否直接传递templist列表中的模板对象。

这个肯定不行了,listkey是用来渲染option value值的,怎么可能是一个模板对象呢?

LZ这样的想法出于什么目的,是要搞定什么问题?

[size=large]楼主你不要想着Struts2的select标签有多么强大,当你提交表单后,对于select标签,也只能传给后台[color=red]listKey="id"[/color],listKey所指定的值。别的不会传递任何东西,当然有关栏目的名称,根本就不会传到后台,这个和Html中的select一样的。

只不过在后台接收到id之后,根据你select中的name属性column.temp.id(这个也相当于html中的name),然后利用java的反射机制,调用你模板中的setId()方法,为你的模板属性id赋值,只能做到这一点。明白了吗。

置于你说的直接获取模板,是做不到的。
最多也只能通过我上面给你说的方法,再说中写法,也和你数据库中表对应着的,数据库中表模板和栏目是多对一关系,所以在你保存栏目的时候,只需要模板的id就行了,因为这个id就是你栏目表的外键,既然是外键,那你也就可以通过该id获取模板的信息了。[/size]