JSF 无法获取自定义复合输入组件的渲染器

标签 jsf jsf-2 composite-component

我正在构建自定义 JSF 复合组件,以便输入周期。我有这个模型:

public class Periodicity implements Serializable {

    private PeriodicityType type;

    private Integer value = 0;

    public PeriodicityExchange() {
        super();
    }

    /**Getter and setters**/

}

其中PeriodicityType是一个包含DAYWEEKMONTHYEAR的枚举>.

该模型的输入组件由 p:spinner 组成。元素用于选择数值,h:selectOneMenu 用于选择周期类型。该组件运行良好,但现在我想要一个 java 类支持它,所以我修改了我的 Facelet 文件:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:composite="http://xmlns.jcp.org/jsf/composite"
    xmlns:p="http://primefaces.org/ui">

<composite:interface componentType="periodicityInput">
    <composite:attribute name="value" type="model.Periodicity" />
</composite:interface>

<composite:implementation>
    <div class="col-xs-2">
        <p:spinner binding="#{cc.periodicityValue}"
            value="#{cc.attrs.value.value}" min="0" />
    </div>
    <div class="col-xs-3">
        <h:selectOneMenu binding="#{cc.periodicityType}"
            value="#{cc.attrs.value.type}" styleClass="form-control">
            <f:selectItem itemLabel="No periodicity" noSelectionOption="true" />
            <f:selectItem itemLabel="Days" itemValue="DAY" />
            <f:selectItem itemLabel="Weeks" itemValue="WEEK" />
            <f:selectItem itemLabel="Months" itemValue="MONTH" />
            <f:selectItem itemLabel="Years" itemValue="YEAR" />
        </h:selectOneMenu>
    </div>
</composite:implementation>

</html>

这是我的 java 类(基于 this BalusC's tutorial )。它使用 faces-config.xml 文件注册为组件:

public class PeriodicityInput extends UIInput implements NamingContainer {

    private UIInput periodicityValue;

    private UIInput periodicityType;

    @Override
    public void encodeBegin(FacesContext context) throws IOException {
        super.encodeBegin(context);
    }

    @Override
    protected Object getConvertedValue(FacesContext context, Object newSubmittedValue)
            throws ConverterException {
        try {
            return new PeriodicityExchange(
                    Integer.parseInt(newSubmittedValue.toString().split("-")[0]),
                    newSubmittedValue.toString().split("-")[1]);
        } catch (Exception ex) {
            throw new ConverterException(ex);
        }
    }

    public String getFamily() {
        return COMPONENT_FAMILY;
    }

    public UIInput getPeriodicityType() {
        return periodicityType;
    }

    public UIInput getPeriodicityValue() {
        return periodicityValue;
    }

    @Override
    public Object getSubmittedValue() {
        return periodicityValue.getSubmittedValue() + "-" + periodicityType.getSubmittedValue();
    }

    public void setPeriodicityType(UIInput periodicityType) {
        this.periodicityType = periodicityType;
    }

    public void setPeriodicityValue(UIInput periodicityValue) {
        this.periodicityValue = periodicityValue;
    }

}

问题是,一旦我使用 componentType 属性将我的组件绑定(bind)到 java 类,该组件就会停止渲染。 encodeBegin 被调用,但进行了一些进一步的调试,我注意到当 JSF 尝试获取复合组件的渲染器时,它返回 null。 UIComponentBase 类中的方法 getRenderer(FacesContext) 尝试访问 context.getRenderKit().getRenderer(getFamily(), rendererType),其中该系列的计算结果为 javax.faces.InputrendererTypejavax.faces.Composite

我正在使用 Mojarra 2.2.12。我在这里缺少什么?

最佳答案

where the family evaluates to javax.faces.Input

这是不正确的。它应该是 javax.faces.NamingContainer,即 UINamingContainer.COMPONENT_FAMILY 的常量值。 .

下面的 COMPONENT_FAMILY 在使用静态导入进行重构期间可能会出现困惑:

@Override
public String getFamily() {
    return COMPONENT_FAMILY;
}

上面实际上继承自UIInput,但它必须是UINamingContainer。最好用 FQN 指定。

@Override
public String getFamily() {
    return UINamingContainer.COMPONENT_FAMILY;
}

关于JSF 无法获取自定义复合输入组件的渲染器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39367862/

相关文章:

java - jsf:生成另一个panelGrid

java - 带有 Java Server Faces 的 HTTPS

java - JSF 从子类中选择项目

javascript - 如何仅隐藏特定页面上的公共(public)链接?

MultilingualString 对象的 JSF 复合组件

jsf - 在复合上使用新的 xmlns.jcp.org 命名空间会导致 java.util.concurrent.ConcurrentHashMap.putIfAbsent 处的 java.lang.NullPointerException

java - JSF 网络应用程序中 URL 栏地址和页面/文件/操作之间的契约(Contract)是什么?

javascript - 如何解决与 primefaces jquery 的冲突

java - JSF 2 复合组件不使用 f :ajax 更新值

database - 如何填充 h :selectOneMenu from database? 的选项