访问支持组件中的 JSF2 复合组件属性

发布于 2025-01-06 20:38:01 字数 2646 浏览 0 评论 0原文

我正在开发一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

离线来电— 2025-01-13 20:38:01

我的猜测是构造函数引用这些属性还为时过早。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文