如何使JSF定制组件将定制类型存储为其值?

时间:2019-01-13 23:39:45

标签: jsf type-conversion custom-component

似乎足够基本...

我有一个自定义的JSF组件及其关联的渲染器。渲染器执行decodeencodeEnd

decode中,我通过component.setSubmittedValue(ctx.getExternalContext().getRequestParameterMap().get(c.getClientId()));成功检索了提交的值

encodeEnd中,我基本上创建了标记,如果component.getValue()不为空,则将其内容插入标记中。到目前为止一切顺利。

问题是getValue()只能是String。我有代表复合数据类型的自定义类,我想将其用作组件的本地值。但不起作用-JSF转换为String

我还尝试使用component.getAttributes()中的decode-在我的自定义对象中键入private static final String someKey = "asd"。但是后来在encodeEnd,地图中没有值/键。

我希望该组件的用户能够在其后备bean中指定自定义数据类型,而不必担心在客户端/服务器之间对文本表示进行序列化/反序列化。大概我必须为此使用转换器?但是,如何为自定义组件设置默认且不可变的转换器?

1 个答案:

答案 0 :(得分:0)

问题有足够简单的解决方案。在Renderer类内部(如果直接使用Component类,则直接进入Component类):

@Override
public Object getConvertedValue(FacesContext context, UIComponent component, Object submittedValue) throws ConverterException {
    SomeCustomObject thing;
    //... do magic to create SomeCustomObject based on submittedValue
    return thing;
}

现在,只要在该组件上调用getValue(),就会返回SomeCustomObject,您可以放心地将其强制转换。同样在后备bean中,可以使用SomeCustomObject作为类型。

还要注意,在实际的渲染器中调用component.getValue()时,它也会返回SomeCustomObject,因此,如果要恢复状态,则必须转换回其String表示形式。

有关更多详细信息,请参见上面的@Kukeltje的答案,并在以下位置检查素数日历组件的处理方式:https://github.com/primefaces/primefaces/blob/master/src/main/java/org/primefaces/component/calendar/BaseCalendarRenderer.java

有关另一个更简洁明了的图示,请同时查看@BalusC的答案。