------------------编辑开始----------------
感谢wu_07 的指点:如果使用myface,可以使用<t:selectOneMenu 其中有属性displayValueOnly属性,就是做这个用的,根本不用自己写convert
<t:selectOneRadio id="sex" value="#{bean.sex}" displayValueOnly="true">
<f:selectItems value="#{InitParam.sexList}" />
</t:selectOneRadio>
我去研究一下源码:)
------------------编辑开结束,原文开始----------------
这几天为了 JSF 自定义Converter苦恼了一阵子。要实现的功能和简单,把数字转换成数据库中相应的汉字,比如性别,表中的值是0和1,我们要呈现给用户的,当然是男和女。
因为有几个相同的东西也要转换,比如婚否、服务种类==,我只想用1个Converter解决,所以要传几个参数:
public class LabelConverterTag extends ConverterTag {
private String beanName;
private String beanProperty;
public LabelConverterTag() {
}
public Converter createConverter() throws JspException {
LabelConverter labelConverter = (LabelConverter) super.createConverter();
labelConverter.setBeanName(beanName);
labelConverter.setBeanProperty(beanProperty);
return labelConverter;
}
public void setBeanName(String beanName) {
this.beanName = beanName.trim();
}
public void setBeanProperty(String beanProperty) {
this.beanProperty = beanProperty.trim();
}
转换标签就是这样,下面是真正的转换器
public class labelConverter implements Converter {
private String beanName;
private String beanProperty;
private Object label;
public Object getAsObject(FacesContext arg0, UIComponent arg1, String arg2)
throws ConverterException {
return arg2;
}
public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2)
throws ConverterException {
FacesContext context = FacesContext.getCurrentInstance();
label = arg2;
if (StringUtils.isBlank(String.valueOf(arg2))) {
return "";
}
if (StringUtils.equals(beanName, "InitParam")) {
if(StringUtils.equals(beanProperty, "serviceList")){
List genericSexInfoList = (List) context.getApplication().createValueBinding("#{InitParam.serviceList}").getValue(context);
getLabel(genericSexInfoList,arg2);
}else if(StringUtils.equals(beanProperty, "sexList")){
List genericSexInfoList = (List) context.getApplication().createValueBinding("#{InitParam.sexList}").getValue(context);
getLabel(genericSexInfoList,arg2);
}
}else if(StringUtils.equals(beanName, "InitTwoParam")){
if(StringUtils.equals(beanProperty, "marryList")){
List sinkokuInfoList = (List) context.getApplication().createValueBinding("#{InitParam.marryList}").getValue(context);
getLabel(sinkokuInfoList,arg2);
}
}
return String.valueOf(label);
}
private void getLabel(SelectItem selectItem,Object value){
if (StringUtils.equals(String.valueOf(selectItem.getValue()).trim(), String.valueOf(value).trim())) {
label=selectItem.getLabel().replaceFirst("└", "");
}
}
private void getLabel(List SelectItems,Object value){
if(!(SelectItems==null||SelectItems.size()==0)){
Iterator iter = SelectItems.iterator();
while(iter.hasNext()){
Object item = (Object)iter.next();
if(item instanceof SelectItemGroup){
getLabel((SelectItemGroup)item,value);
}else{
getLabel((SelectItem)item,value);
}
}
}
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
public void setBeanProperty(String beanProperty) {
this.beanProperty = beanProperty;
}
}
接下来是注册转换器
<converter>
<converter-id>test.LabelValue</converter-id>
<converter-class>test.LabelConverter</converter-class>
</converter>
注册标签labelValue.tld
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd ">
<taglib>
<tlib-version>0.03</tlib-version>
<jsp-version>1.2</jsp-version>
<short-name>labelValue</short-name>
<uri>http://java.sun.com/jsf/labelValue</uri>
<description>
This tag library contains a battle map tag.
</description>
<tag>
<name>labelValue</name>
<tag-class>test.LabelConverterTag</tag-class>
<attribute>
<name>converterId</name>
<required>true</required>
</attribute>
<attribute>
<name>beanName</name>
<required>true</required>
</attribute>
<attribute>
<name>beanProperty</name>
<required>false</required>
</attribute>
</tag>
</taglib>
在xml中注册
<taglib>
<taglib-uri>http://java.sun.com/jsf/labelValue</taglib-uri>
<taglib-location>/WEB-INF/labelValue.tld</taglib-location>
</taglib>
ok,可以在页面中使用了
.......
<%@ taglib uri="http://java.sun.com/jsf/labelValue " prefix="l"%>
...
<f:view>
<h:outputText value="
..............
<h:outputText value="#{bean.sex}">
<l:labelValue converterId="test.LabelValue" beanName="InitParam" beanProperty="sexList"/>
</h:outputText>
..............
</f:view>
.....
---------------------------代码完成分割线-------------------------------------
这段代码很简单,用起来似乎也没什么问题,我自己看代码也找不出问题。可惜问题还是出现了。当我在使用这个
转换器的页面,疯狂F5,发现它并不是总好用,偶尔不把1转换成男,只呈现1,这个时候控制台报错:
ERROR ViewTag:107 - Error writing endDocument
估计是也面没加载完,还没有执行</f:view>。跟踪日志,发现这个时候程序没有走tag,而直接去了converter,这样
converter需要的参数就没有正常传递,导致不能正确转换。
这个问题困扰了几天,很遗憾没有解决,希望达人们给帮助分析解决一下。对JSF还是不熟悉,只能改成了标准的jsp标签来做
<i:labelValue beanName="InitParam" beanProperty="sexList">
<h:outputText value="#{bean.sex}"/>
</i:labelValue>
细节就不写了,网上可以找到很多例子。