当组件具有渲染器时,似乎不使用转换器

时间:2015-08-11 04:26:43

标签: jsf jsf-2 converter renderer

众所周知,我们可以轻松编写自定义对流器并将其注册到组件,如下所示:

<f:converter converterId="cId" />

<f:converter binding="#{mybean}" />

对我们的需求进行了研究。但现在考虑UIInput的源代码,它们负责确切的转换(评论已被忽略):

 protected Object getConvertedValue(FacesContext context,
                                       Object newSubmittedValue) throws ConverterException {
        Renderer renderer = getRenderer(context);
        Object newValue;

        if (renderer != null) {
            newValue = renderer.getConvertedValue(context, this,
                 newSubmittedValue); // <----------- 1
        } else if (newSubmittedValue instanceof String) {
            Converter converter = getConverterWithType(context);
            if (converter != null) {
                newValue = converter.getAsObject(context, this,
                     (String) newSubmittedValue);// <----------- 2
            } else {
                newValue = newSubmittedValue;
            }
        } else {
            newValue = newSubmittedValue;
        }
        return newValue;
    }

因此,很清楚我们选择了应该使用的转换器。此外,据我所知,如果某个组件具有单独的Renderer,我们就无法应用在facelet中指定为标记的自定义转换器(因为if(renderer != null){...} else if(newSubmittedValue instanceof String){...})。例如<h:inputText />组件类为UIInput,并且它还有自定义com.sun.faces.renderkit.html_basic.TextRenderer,因此getRenderer(context)会返回不是null的内容。因此,我们应该跳过converter标记指定的转换,即使我们将其定义为

<h:inputText  value="#{myBean.prop}"/>
    <f:converter inding="#{bean}" />  
</h:inputText>

inputText有一个自定义渲染器,因此转换器不应该执行此处指定的任何操作:

 Converter converter = getConverterWithType(context);
 if (converter != null) {
     newValue = converter.getAsObject(context, this,
           (String) newSubmittedValue);// <----------- 2
 } else {
       newValue = newSubmittedValue;
 }
你能解释一下吗?转换实际如何运作以及Renderer转换器与我们的自定义converter

之间的差异是什么?

1 个答案:

答案 0 :(得分:2)

实际上,渲染器也是如此。另请参见Renderer#getConvertedValue()的javadoc。

  

尝试将以前存储的状态信息转换为此组件所需类型的对象(可选地使用此组件的已注册Converter(如果有的话))。如果转换成功,则应从此方法返回新值;如果没有,则应抛出ConverterException

如果Mojarra中有<h:inputText>,则可以在HtmlBasicInputRenderer中找到源代码。

此设计允许渲染器完全控制转换步骤,并在必要时操作此步骤。请注意,可以声明性地(通过faces-config.xml)覆盖(标准)组件的渲染器,而无需在视图中更改组件本身。另请注意术语&#34;自定义渲染器&#34;在你的问题中并不完全正确。它只是标准的渲染器。我们谈论一个&#34;自定义渲染器&#34;只有当Web应用程序提供自己的应用程序时,才会覆盖标准的应用程序。