今天在使用Struts 2.0 <s:select>标签的时候碰到了错误:
tag 'select', field 'list', name 'university': The requested list key 'universities' could not be resolved as a collection/array/map/enumeration/iterator type.
google,baidu找了很多方法,都无法解决,后来终于发现了问题所在,其实是小问题,在这里总结一下,以便大家以后会出现同类错误。
<s:select>是下拉列表的标签,有很多种用法,例如直接指定一个列表,为其赋值:
<s:select name="university" headerKey="-1" headerValue="请选择" list="{'华南理工大学', '华中科技大学', '福州大学'}"/>
有时候,我们需要从数据库里面取得所谓的“数据字典”,填充到下拉列表中,
先来看看具体的代码吧:
register.jsp的部分代码片段:
<form id="form1" action="register.action" method="POST">
<s:select name="university" headerKey="-1" headerValue="请选择" list="universities" listKey="uniId" listValue="uniName"/>
</form>
list属性指定了一个变量universities,这个变量是register这个action的一个成员属性,其类型是List<University>:
…………
public class Register extends ActionSupport {
private List<University> universities;
public List<University> getUniversities() {
return universities;
}
public void setUniversity(String university) {
this.university = university;
}
@Override
public String execute() throws Exception {
universities = uniService.getUniversityList();
…………
}
}
这里省略了很多东西,只是为了说明select标签的用法,uniService.getUniversityList()可以从数据库中获取一个University的列表,这里省略了uniService的声明和AutoWire。当然,除了用List以外,还可以用Map。
struts.xml和Spring的配置文件把register这个action映射到Register.java。具体如何整合Struts 2.0,Spring和Hibernate,网上很多教程,也可以参考Netbeans下的:
http://developers./blog/functionalca/category/JavaEE这里省略具体细节。
如果我们直接运行register.jsp,将会得到我们开头所描述的错误,其实原因很简单,因为第一次运行这个页面的时候,Register这个action根本没有被实例化,因此也就没有universities这个变量。那怎么办呢?很简单,首先,在register.jsp前面加一个页面,例如index.jsp:
<s:url id="regForm" action="register">
<s:param name="type">getForm</s:param>
</s:url>
<s:a href="%{regForm}">注册</s:a>
这个页面里面很简单,定义了一个url,这个url会提交register这个action,然后再定义一个超链接指向这个url。这样,当用户点击超链接的时候,action就会被实例化,universities这个变量也就可以得到了。type这个属性有什么用呢?先来看看我们需要在action的execute方法做一些改动:
public String execute() throws Exception {
if (type != null && type.equals("getForm")) {
universities = uniService.getUniversityList();
return INPUT;
}
if (type != null && type.equals("submit")) {
…………
}
}
由于我们的表单可能会再一次提交(例如注册),因此必须区分是初始化页面,还是要提交页面。用一个属性来区别就可以了。当然,我们还需要在register.jsp里面声明一个这样的属性,否则再一次提交表单的时候这个变量就取不到了:
<input type="hidden" name="type" value="submit"/>
最后,运行index.jsp,点击超链接,页面就能正常显示了。