我们的数据库中有数值,表示双值状态。当然,这将完全匹配布尔值,但 oracle 没有这样的数据类型。数据库中的 NUMBER(1,0) 类型与 Java 中的 java.lang.Short 类型匹配(有时他们使用 NUMBER(*,0) 来表示与 java.math.BigDecimal 匹配的布尔值)。
由于它在某种程度上很明显,我想在视图中提供 ice:selectBooleanCheckbox 作为值表示和 UIComponent 给用户。(我使用 IceFaces 作为 JSF 实现)
由于某些指定 JSF 的人认为总是将 ice:selectBooleanCheckbox 或 JSF h:selectBooleanCheckbox 的值与模型中的布尔值相匹配是显而易见的,因此组件的渲染器从不调用任何转换器,即使您指定了一个: 在 java.net 上讨论的问题
因此我尝试了以下方法:
我创建了一个转换器来在 UIComponent 中指定它:
public class BooleanBigDecimalConverter implements Converter {
public Object getAsObject(FacesContext context, UIComponent component, String str) {
if (StringUtils.isEmptyString(str)) {
return new BigDecimal(0);
}
if (str.equals("true")) {
return new BigDecimal(1);
} else {
return new BigDecimal(0);
}
}
public String getAsString(FacesContext context, UIComponent component, Object obj) {
if (obj != null) {
String str = obj.toString();
if (str.equalsIgnoreCase("1")
|| str.equalsIgnoreCase("yes")
|| str.equalsIgnoreCase("true")
|| str.equalsIgnoreCase("on")) {
return "true";
} else {
return "false";
}
}
return "false";
}
}
转换器在渲染阶段工作正常(getAsString 方法被正确调用),但 getAsObject 方法(忽略它目前不正确,因为它没有被调用,所以如果它被调用它将被修复!)是从未调用过,因为在 UIComponent 的渲染器中没有预见到转换器,就像您可以在此处看到的那样(来自 com.icesoft.faces.renderkit.dom_html_basic.CheckboxRenderer 的片段):
public Object getConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object submittedValue) throws ConverterException
{
if(!(submittedValue instanceof String))
throw new ConverterException("Expecting submittedValue to be String");
else
return Boolean.valueOf((String)submittedValue);
}
所以这会导致 IllegalArgumentException,因为在 UpdateModelValues 阶段它试图将布尔值应用于数值(请忽略 BigDecimal/Short 混淆......无论如何它只是一个数值类型!)。
所以我尝试用这样的新渲染器覆盖渲染器:
import com.icesoft.faces.component.ext.renderkit.CheckboxRenderer;
public class CustomHtmlSelectBooleanCheckbox extends CheckboxRenderer {
public Object getConvertedValue(FacesContext context, UIComponent component, Object submittedValue) throws ConverterException {
Converter converter = ((ValueHolder) component).getConverter();
return converter.getAsObject(context, component, (String) submittedValue);
}
}
并像这样在 faces-config.xml 中注册它:
<render-kit>
<renderer>
<component-family>com.icesoft.faces.HtmlSelectBooleanCheckbox</component-family>
<renderer-type>com.icesoft.faces.Checkbox</renderer-type>
<renderer-class>com.myapp.web.util.CustomHtmlSelectBooleanCheckbox</renderer-class>
</renderer>
</render-kit>
我想这应该是正确的,但是从未调用过覆盖的方法“getConvertedValue”,也没有调用 getAsObject() 方法,所以我想我在注册自定义渲染器时犯了一个错误,但我找不到更多文档或提示如何正确执行此操作,尤其是如何找到正确的组件系列(我查找了我在 icefaces.taglib.xml 中使用的那个)和正确的渲染器类型。
因此,我不想编辑完整的模型。任何提示,如何解决?