JSF自定义组件:支持自定义类型的参数,永远不会调用属性setter

时间:2012-11-21 11:00:34

标签: java jsf jsf-2 attributes custom-component

我根据许多教程之一(我使用 PrimeFaces )创建了自定义 JSF 组件,我添加了一个成功传递给组件的参数。

<c:custom command="command"/>
public void setCommand(String command) {
    log.debug("setCommand {}", command);
    this.command = command;
}

但我需要自定义类型的论点,这是我在教程中找不到的东西,它们只处理最琐碎的案例。

<c:custom image="#{currentImageBean.image}"/>
public void setImage(Object image) {
    log.debug("setImage {}", image);
    this.image = (Image) image;
}

bean返回 Image 类型的对象,但不调用setter。我预计这会起作用,因为否则一个好的教程应该提到这个案例,但是现在我遇到了更糟糕的错误:没有任何反应,日志中没有任何内容表明为什么......那么,出了什么问题,我需要改变什么,在哪里寻找潜在的错误?

1 个答案:

答案 0 :(得分:6)

这与自定义类型无关。这与使用文字(静态)值而不是attributename="attributevalue"attributename="#{attribute.value}"中的EL有关。

此行为是预期的并且符合规范。 EL表达式(ValueExpression s)的属性值由UIComponent#setValueExpression()设置。它们应该仅在它们确实被请求时才被评估,通常在视图渲染时间期间。在烘焙UIComponent实例时,不应该直接评估它们,因为这会破坏动态值表达式的性质(根据数据表的当前迭代轮次来考虑)。

最好是将可以保存EL值表达式的属性的getter / setter委托给UIComponent#getStateHelper()而不是本地属性。 setValueExpression()最终也会在StateHelper中结束。 UIComponent#getAttributes()也会解析StateHelper

中的值
public Image getImage() {
   return (Image) getStateHelper().eval("image");
}

public void setImage(Image image) {
    getStateHelper().put("image", image);
}

请注意,没有本地财产。因此,当您需要属性的(已评估)值时,只需调用getter。

为了实现初始功能需求,即set属性的日志记录,您可能希望将日志记录语句添加到委托给setValueExpression()的{​​{1}}覆盖。

super