JSF 条件转换器

JSF conditional converter

我创建了一个非常通用的 jsf 复合组件,它从通用行数据中呈现一个 primefaces dataTable。

对于应该呈现的每一行,我有一个名为 ColumnDescription 的 pojo,其中包含 header 名称和用于获取数据的行数据索引。

这工作正常,但现在我有允许在列上设置可选转换器的请求。

所以我用 converterId 扩展了 ColumnDescription。 问题是,如果 ColumnDescription 中的 converterId 不为空,我只需要将转换器附加到。

第一个想法:

<h:outputText value="#{row[column.rowBeanProperty]}">
<c:if test="#{column.hasConverter}">
    <f:converter converterId="#{column.converterId}" />
</c:if>

这没有用。 if 标签中的测试甚至不会被评估。 我认为这是因为将评估 jsp 标签的不同阶段。

第二个想法 使用渲染的属性作为条件

<h:outputText value="#{row[column.rowBeanProperty]}">
<ui:fragment rendered="#{column.hasConverter}">
    <f:converter converterId="#{column.converterId}" />
</ui:fragment>

这不起作用,因为转换器需要附加到可编辑值组件

TagException: /components/dataReport.xhtml @38,80 <f:converter> Parent not an instance of ValueHolder: com.sun.faces.facelets.tag.ui.ComponentRef@35b683c2

是否有机会有条件地添加转换器?

提前致谢 塞巴斯蒂安

您可以做的是编写自己的转换器。看How create a custom converter in JSF 2?. If you know you can get a converter by calling context.getApplication().createConverter(converterId),很简单:

@FacesConverter("optionalConverter")
public class OptionalConverter implements Converter {

  private String converterId;

  private boolean disabled;

  @Override
  public Object getAsObject(FacesContext context, UIComponent component, String value) {
    return disabled
           ? value
           : context.getApplication().createConverter(converterId).getAsObject(context, component, value);
  }

  @Override
  public String getAsString(FacesContext context, UIComponent component, Object value) {
    if (value == null) {
      return null;
    }
    return disabled
           ? value.toString()
           : context.getApplication().createConverter(converterId).getAsString(context, component, value);
  }

  // Getters and setters
}

然后为该转换器创建一个标签。参见 How to create a custom Facelets tag?。因此,在 /WEB-INF/:

中创建一个名为 my.taglib.xml 的文件
<?xml version="1.0" encoding="UTF-8"?>
<facelet-taglib xmlns="http://java.sun.com/xml/ns/javaee"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
                version="2.0">
  <namespace>http://my.com/jsf/facelets</namespace>

  <tag>
    <tag-name>optionalConverter</tag-name>
    <converter>
      <converter-id>optionalConverter</converter-id>
    </converter>
    <attribute>
      <name>converterId</name>
      <required>true</required>
      <type>java.lang.String</type>
    </attribute>
    <attribute>
      <name>disabled</name>
      <required>false</required>
      <type>boolean</type>
    </attribute>
  </tag>

</facelet-taglib>

并将其添加到 web.xml:

<context-param>
  <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
  <param-value>/WEB-INF/my.taglib.xml</param-value>
</context-param>

测试:

Enabled:
<h:outputText value="1234">
  <my:optionalConverter converterId="javax.faces.Number" />
</h:outputText>
Disabled:
<h:outputText value="1234">
  <my:optionalConverter converterId="javax.faces.Number" disabled="true" />
</h:outputText>

输出:"Enabled: 1,234 Disabled: 1234".