struts2 checkboxlist 的一个问题
关键字: struts2 checkboxlist用struts2的checkboxlist遇到一个问题。
下面是java对象。
package cn.jolestar.struts;
/**
* @author jolestar
*
*/
public class Language {
private Long id;
private String name;
/**
*
*/
public Language() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((id == null) ? 0 : id.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Language other = (Language) obj;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
return true;
}
}
package cn.jolestar.struts;
import java.util.List;
/**
* @author jolestar
*
*/
public class Album {
private Long id;
private String name;
private List<Language> languages;
/**
*
*/
public Album() {
}
public List<Language> getLanguages() {
return languages;
}
public void setLanguages(List<Language> languages) {
this.languages = languages;
}
}
下面是jsp标签:
<s:checkboxlist name="album.languages" list="languages" listValue="name" listKey="id" > </s:checkboxlist>
action中有个getLanguages()方法,返回数据库中的所有语言。按道理我编辑Album的时候,checkboxlist中Album的已经拥有的语言会自动选中。但怎么弄,它就是不选中。没办法,看了一下struts2的相关源码,才明白了。
struts2 checkboxlist 的freemarker模板:
<#assign itemCount = 0/>
<#if parameters.list?exists>
<@s.iterator value="parameters.list">
<#assign itemCount = itemCount + 1/>
<#if parameters.listKey?exists>
<#assign itemKey = stack.findValue(parameters.listKey)/>
<#else>
<#assign itemKey = stack.findValue('top')/>
</#if>
<#if parameters.listValue?exists>
<#assign itemValue = stack.findString(parameters.listValue)/>
<#else>
<#assign itemValue = stack.findString('top')/>
</#if>
<#assign itemKeyStr=itemKey.toString() />
<input type="checkbox" name="${parameters.name?html}" value="${itemKeyStr?html}" id="${parameters.name?html}-${itemCount}"<#rt/>
<#if tag.contains(parameters.nameValue, itemKey)>
checked="checked"<#rt/>
</#if>
<#if parameters.disabled?default(false)>
disabled="disabled"<#rt/>
</#if>
<#if parameters.title?exists>
title="${parameters.title?html}"<#rt/>
</#if>
<#include "/${parameters.templateDir}/simple/scripting-events.ftl" />
<#include "/${parameters.templateDir}/simple/common-attributes.ftl" />
/>
<label for="${parameters.name?html}-${itemCount}" class="checkboxLabel">${itemValue?html}</label>
</@s.iterator>
<#else>
</#if>
if tag.contains(parameters.nameValue, itemKey)这个if语句决定该checkbox是否选中。tag.contains()最终调用的是org.apache.struts2.util.ContainUtil中的这个方法:
public static boolean contains(Object obj1, Object obj2) {
if ((obj1 == null) || (obj2 == null)) {
//log.debug("obj1 or obj2 are null.");
return false;
}
if (obj1 instanceof Map) {
if (((Map) obj1).containsKey(obj2)) {
//log.debug("obj1 is a map and contains obj2");
return true;
}
} else if (obj1 instanceof Collection) {
if (((Collection) obj1).contains(obj2) || ((Collection) obj1).contains(obj2.toString())) {
//log.debug("obj1 is a collection and contains obj2");
return true;
}
} else if (obj1.getClass().isArray()) {
for (int i = 0; i < Array.getLength(obj1); i++) {
Object value = null;
value = Array.get(obj1, i);
if (value.equals(obj2)) {
//log.debug("obj1 is an array and contains obj2");
return true;
}
}
} else if (obj1.toString().equals(obj2.toString())) {
//log.debug("obj1 is an object and it's String representation equals obj2's String representation.");
return true;
} else if (obj1.equals(obj2)) {
//log.debug("obj1 is an object and equals obj2");
return true;
}
//log.debug("obj1 does not contain obj2: " + obj1 + ", " + obj2);
return false;
}
tag.contains(parameters.nameValue, itemKey)的参数parameters.nameValue是該标签的值,在这里就是album.languages, parameters.list 是languages,itemKey是循环中的当前language的id。album.languages包含的是Language对象,而struts2却在其中查找itemKey--就是Language的id,当然就无法查找到,所以不能自动选中。
我把checkboxlist的模板改了一下。
<#assign itemCount = 0/>
<#if parameters.list?exists>
<@s.iterator value="parameters.list" id="it">
<#assign itemCount = itemCount + 1/>
<#if parameters.listKey?exists>
<#assign itemKey = stack.findValue(parameters.listKey)/>
<#else>
<#assign itemKey = stack.findValue('top')/>
</#if>
<#if parameters.listValue?exists>
<#assign itemValue = stack.findString(parameters.listValue)/>
<#else>
<#assign itemValue = stack.findString('top')/>
</#if>
<#assign itemKeyStr=itemKey.toString() />
<input type="checkbox" name="${parameters.name?html}" value="${itemKeyStr?html}" id="${parameters.name?html}-${itemCount}"<#rt/>
<#if tag.contains(parameters.nameValue,it)>
checked="checked"<#rt/>
</#if>
<#if parameters.disabled?default(false)>
disabled="disabled"<#rt/>
</#if>
<#if parameters.title?exists>
title="${parameters.title?html}"<#rt/>
</#if>
<#include "/${parameters.templateDir}/simple/scripting-events.ftl" />
<#include "/${parameters.templateDir}/simple/common-attributes.ftl" />
/>
<label for="${parameters.name?html}-${itemCount}" class="checkboxLabel">${itemValue?html}</label>
</@s.iterator>
<#else>
</#if>
就是将tag.contains(parameters.nameValue, itemKey)改成了tag.contains(parameters.nameValue,it),it就是当前循环的Language对象,在struts2的iterator 标签里设置
<@s.iterator value="parameters.list" id="it">.(注意:如果是最新版的struts2,应该用var 而不是id).
这样就好了。需要注意的是language必须正确overwrite equals和hashCode方法。
发表评论
- 浏览: 45773 次
- 性别:

- 来自: 北京

- 详细资料
搜索本博客
最近加入圈子
链接
最新评论
-
四个有害的java习惯
不同观点: 1:一般的编辑器都把类数据和方法数据用颜色区分开,一目了然。加个a ...
-- by tom.liu -
四个有害的java习惯
to 42087743但问题在于javabean只是很少一部分java类,并且对 ...
-- by jolestar -
四个有害的java习惯
to jolestar : 你已经说了,javabean里只需要看一下几 ...
-- by 42087743 -
四个有害的java习惯
to coolnight 你说的这种情况只是javabean里的情况,而java ...
-- by jolestar -
四个有害的java习惯
很不同意第四点field声明只有一行, 把field声明放在最上面,更容易看清c ...
-- by coolnight






评论排行榜