我在JSF 2.1 vanilla(在glassfish 3.1上)中使用复合组件时遇到了一些麻烦。我的问题的简化版本在这里:
[复合成分]
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:cc="http://java.sun.com/jsf/composite">
<!-- INTERFACE -->
<cc:interface>
<cc:attribute name="value" required="true"/>
<cc:attribute name="title" required="false" default=""/>
<cc:editableValueHolder name="inputTarget" targets="labeledInputField"/>
</cc:interface>
<!-- IMPLEMENTATION -->
<cc:implementation>
<p:inputText id="labeledInputField"
label="#{cc.attrs.title}"
value="#{cc.attrs.value}"
title="#{cc.attrs.title}">
<cc:insertChildren/>
</p:inputText>
</cc:implementation>
</html>
[在]中实施
<!-- thisPerson is passed in via ui:param to the facelet containing this code.
it works in other (non-composite) components on the page -->
<comp:labeledInputText
id="baseUsername"
value="#{controller.username}"
title="#{bundle.Username}">
<f:validator for="inputTarget" binding="#{thisPerson.usernameValidator}"/>
<f:converter for="inputTarget" converterId="#{whiteSpaceTrimConverter}"/>
</comp:labeledInputText>
问题是,“thisPerson.usernameValidator”正在评估为NULL,然后导致com.sun.faces.facelets.tag.jsf.ValidatorTagHandlerDelegateImpl跳转到尝试通过“validatorID”加载验证器的代码“因为我们试图通过”绑定“发送验证器,所以没有设置。有没有办法让复合材料来评估ui:param值,或者不需要重新设计验证器的解决方法(这是一个巨大的反模式,我现在没有时间来扭转损坏)。假设验证器已通过绑定进入。
我知道复合材料有效,因为在不同的facelet中,我有一个针对具体bean引用的验证器绑定,而不是一个“软”引用,它就像一个冠军。
TIA
答案 0 :(得分:2)
在不知道您的确切JSF实现的情况下,我将假设Mojarra,您可能会遇到以下已知错误。
http://java.net/jira/browse/JAVASERVERFACES-2040
无论这是否是您的确切问题,您都可以尝试禁用部分状态保存,看看这是否可以解决您的问题。如果它确实那么这意味着你正面临这个问题,这在Mojarra的后期版本中显然是(修复了?)。
另一种可能性是简单地使用renderFacet
而不是insertChildren
,并以方面的形式插入验证器。