如何在JSF中注册自定义渲染器?
-
02-10-2019 - |
题
我们的数据库中有数值,代表两个值状态。当然,这将完全匹配布尔值,但是Oracle没有这样的数据类型。数据库中的数字(1,0)类型与Java.lang.short类型匹配Java(有时他们使用数字(*,0)代表布尔值,这些布尔值与Java.math.math.bigdecimal匹配)。
由于它很明显,因此我想在视图中提供ICE:SelectBooleanCheckbox,作为用户的值表示和UIComponent。 (我将冰面用作JSF实施)
由于某些指定JSF的人认为始终匹配冰的值很明显:selectBooleanCheckbox或JSF H中的selectBooleanCheckbox box box框与模型中的布尔值,因此组件的渲染器也永远不会调用任何转换器,即使您指定一个: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-hod(忽略它目前不正确,因为它不管是任何人都不称为,所以如果被称为!)从来没有打过电话,因为在UIComponent的渲染器中,转换器无法预见,就像您可以在此处看到(com.iceseft.faces.renderkit.renderkit.dom_html_basic.checkboxboxrenderer):
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);
}
因此,这会导致非法符号检查,因为在UpdateModelValues阶段,它被试图将布尔值应用于数值(请忽略bigdecimal/short Confusion ...在任何情况下,它只是数值类型!)。
因此,我试图用这样的新渲染器覆盖渲染器:
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中使用的零件)和正确的渲染器型。
因此,我不想编辑完整的模型。有任何提示,如何解决?
解决方案
我们可以解决该问题并正确注册我们的自定义渲染器。
问题是要找到预期渲染器的正确属性。我们的尝试是错误的,因为我发现了如何获取适当的信息。这是一些工作和搜索,但最终解决了问题。
只需在调试模式下启动您的容器,然后在类级别上添加一个断点到派生的类中,自定义渲染器基于(在我的情况下com.iceseft.faces.renderkit.renderkit.dom_html_basic.checkboxboxrenderer)。
在容器启动期间,将达到此断点,在StackTrace中,您会找到faceSconfigurator.configurerenderkits()的呼叫。
该对象包含注册渲染器的数组列表。我搜索了列表中的渲染器,我想覆盖,并可以找到我需要注册自定义渲染器的信息。就我而言,这是faces-config.xml中的正确条目:
<render-kit>
<description>The ICEsoft Renderers.</description>
<render-kit-id>ICEfacesRenderKit</render-kit-id>
<render-kit-class>com.icesoft.faces.renderkit.D2DRenderKit</render-kit-class>
<renderer>
<component-family>javax.faces.SelectBoolean</component-family>
<renderer-type>com.icesoft.faces.Checkbox</renderer-type>
<renderer-class>com.myapp.web.util.CustomHtmlSelectBooleanCheckbox</renderer-class>
</renderer>
</render-kit>
现在,getAsObject() - 转换器中的方法由自定义渲染器调用。如果您不希望在每个SelectBooleanCheckbox上使用转换器:
public Object getConvertedValue(FacesContext context,
UIComponent component, Object submittedValue)
throws ConverterException {
Converter converter = ((ValueHolder) component).getConverter();
if (converter == null) {
if(!(submittedValue instanceof String))
throw new ConverterException("Expecting submittedValue to be String");
else
return Boolean.valueOf((String)submittedValue);
}
return converter.getAsObject(context, component,
(String) submittedValue);
}
否则,您将获得NullPoInterException。
PS:肯定有一种实现此信息的智能方法,但我还不够聪明。 ;-)
其他提示
您没有说您是否正在使用Hibernate,但我认为您必须成为问题。您是否尝试过将数字视为映射中的布尔值?
看到这个 冬眠论坛的线程