如何注册在JSF定制呈现?(How to register a custom renderer in

2019-10-30 05:05发布

我们有数值在我们的数据库中,较二值状态。 当然,这将很好地匹配一个布尔值,但甲骨文没有这样的数据类型。 的数目(1,0)从所述数据库类型被匹配到在Java中java.lang.Short中型(有时他们使用的NUMBER(*,0)来表示布尔值,其被匹配到的java.math.BigDecimal)。

由于它是有点明显,我想提供冰:selectBooleanCheckbox在视图中的值表示和UIComponent给用户。 (我用的ICEfaces为JSF实现)

因为谁规定JSF有些人认为这是有目共睹的总是匹配冰的价值:selectBooleanCheckbox或JSF H:selectBooleanCheckbox模型中的一个布尔值,因此组件的渲染从来没有要求任何转换器,即使你指定一个: 发行disscused在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 /短混乱......它仅仅是在任何情况下的数值类型!)。

所以,我试图用一个新的像这样覆盖渲染器:

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使用)和正确的渲染器型。

我不希望编辑因为这个完整的模型。 任何提示,这可怎么解决?

Answer 1:

我们可以解决这个问题并正确登录我们的自定义呈现。

问题是要找到预期的渲染正确的属性。 我们的尝试是错误的,因为我发现了如何获取相应的信息。 这是一个有点工作和搜索,但它最后的伎俩。

刚开始你在调试模式下的容器,并添加类级别断点到派生类中的自定义呈现是基于(在我的情况com.icesoft.faces.renderkit.dom_html_basic.CheckboxRenderer)。

在容器启动时该断点将达到并在堆栈跟踪,你会发现方法FacesConfigurator.configureRenderKits的()的调用。

这个对象包含注册渲染器的ArrayList。 我搜索名单我也希望能覆盖并能找到我需要注册我的自定义渲染器的信息渲染器。 在我而言,这是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:有肯定是实现这一信息的更聪明的办法,但我不够聪明。 ;-)



Answer 2:

你不说,不管你是使用Hibernate,但我认为你必须是这是一个问题。 您是否尝试过处理的数字作为您的映射一个布尔值?

看到这个线程从休眠论坛



文章来源: How to register a custom renderer in JSF?