访问支持组件中的 JSF2 复合组件属性
我正在开发一个 JSF2/Primefaces 应用程序,但在访问该组件的支持 bean 中的复合组件的接口中定义的属性时遇到问题。
我的组件定义如下:
<!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:h="http://java.sun.com/jsf/html"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface componentType="testComponent">
<composite:attribute name="text" required="true" type="java.lang.String" />
</composite:interface>
<composite:implementation>
<h:outputText value="Passed text is: #{cc.attrs.text}" />
</composite:implementation>
</html>
它存储在名为 text.xhtml
的文件中,该文件位于: application/src/main/webapp/resources/my_component
目录中。
我在另一个页面(这是一个 Facelets 组合元素)上使用此组件,如下所示:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:myc="http://java.sun.com/jsf/composite/my_component"
template="./resources/templates/template.xhtml">
<ui:define name="content">
<h:form id="products">
<myc:test id="test" text="A text" />
</h:form>
</ui:define>
</ui:composition>
支持组件类定义如下:
package my.application.component;
import javax.faces.component.FacesComponent;
import javax.faces.component.UINamingContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@FacesComponent ( value="testComponent" )
public class TestComponent extends UINamingContainer {
Logger log = LoggerFactory.getLogger(TestComponent.class);
public TestComponent() {
log.debug("TestComponent constructor");
log.debug("getAttributes().size(): " + getAttributes().size());
}
}
组件本身按预期工作。使用页面呈现传递的文本是:文本
输出。 此外,记录器输出显示来自 TestComponent
构造函数的日志消息,因此组件 xml 定义似乎已与 TestComponent
类正确绑定。
现在,问题是在 TestComponent 构造函数中调用的 getAttributes() 方法始终返回零大小的映射。 如果我理解正确,我应该能够使用以下调用访问组件接口中声明的 text
属性:
getAttributes().get("text");
TestComponent
类,但它总是返回 null
因为属性映射为空。
我还尝试使用以下调用访问 text
属性:
String text = FacesContext.getCurrentInstance().getApplication()。 evaluateExpressionGet(FacesContext.getCurrentInstance(), "#{cc.attrs.text}", String.class));
但它也会解析为 null
。
我做错了什么?任何提示将不胜感激,因为我不知道下一步要尝试什么。
/图卡斯。
I'm developing a JSF2/Primefaces app and I'm having trouble with accessing attributes defined in an interface of a composite component in this component's backing bean.
My component is defined as follows:
<!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:h="http://java.sun.com/jsf/html"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface componentType="testComponent">
<composite:attribute name="text" required="true" type="java.lang.String" />
</composite:interface>
<composite:implementation>
<h:outputText value="Passed text is: #{cc.attrs.text}" />
</composite:implementation>
</html>
It is stored in a file called text.xhtml
located in: application/src/main/webapp/resources/my_component
directory.
I use this component on another page (which is a Facelets composition element) like so:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:myc="http://java.sun.com/jsf/composite/my_component"
template="./resources/templates/template.xhtml">
<ui:define name="content">
<h:form id="products">
<myc:test id="test" text="A text" />
</h:form>
</ui:define>
</ui:composition>
The backing component class is defined as follows:
package my.application.component;
import javax.faces.component.FacesComponent;
import javax.faces.component.UINamingContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@FacesComponent ( value="testComponent" )
public class TestComponent extends UINamingContainer {
Logger log = LoggerFactory.getLogger(TestComponent.class);
public TestComponent() {
log.debug("TestComponent constructor");
log.debug("getAttributes().size(): " + getAttributes().size());
}
}
The component itself works as expected. The using page renders Passed text is: A text
output.
Also, logger output displays log messages from TestComponent
constructor, so it seems that the component xml definition is correctly bound with the TestComponent
class.
Now, the problem is that the getAttributes()
method invoked in TestComponent
constructor always returns a zero-sized map.
If I understand this correctly, I should be able to access the text
attribute declared in component's interface using a call:
getAttributes().get("text");
in the TestComponent
class, but it always returns null
as the attributes map is empty.
I also tried to access the text
attribute using a call:
String text = FacesContext.getCurrentInstance().getApplication().
evaluateExpressionGet(FacesContext.getCurrentInstance(), "#{cc.attrs.text}", String.class));
but it also resolves to null
.
What am I doing wrong? Any tips will be much appreciated as I have no idea what to try next.
/Tukasz.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我的猜测是构造函数引用这些属性还为时过早。
JSF 将首先构造支持组件的实例,然后在某个时刻为其提供对其属性的引用。在稍后调用的方法中,例如编码方法,您应该可以访问它们。
My guess is that the constructor is too early to reference those attributes.
JSF will construct an instance of the backing component first, and will then at some point give it a reference to its attributes. In a method that's called later, eg the encode method, you should have access to them.