【问题标题】:JSF Backing Component - Composite Component - Stackoverflow ExceptionJSF 支持组件 - 复合组件 - Stackoverflow 异常
【发布时间】:2013-08-22 14:51:33
【问题描述】:

我想使用一个支持组件作为一个层来访问我的复合组件的属性(在其接口中定义)。 我想要实现的是通过我的支持组件类读取我的组件的属性,我在其中返回所提供属性的属性值。

public String getName() {
    if (this.name == null) {
        this.name = getAttributes().get("name");
    }

    return this.name;
}

但是当设置一个新值时,例如通过一个输入字段,我只想将值存储在我的支持 bean 属性中,而不是更新作为属性参数传递给我的复合组件的原始属性的值。

public void setName(final String name) {
    this.name = name;
}

我现在的问题是,当我的支持组件的 getter 第一次或在他生命的某个早期阶段被调用时,如上所示的 getter 代码会导致 Stackoverflow 异常,因为 getAttributes.get("name") 调用我的支持组件(本身)的 getter 而是获取提供给我的复合组件的属性/属性。 有趣的部分是使用一个简单的 getter 只返回 this.name 而不是调用 getAttributes() 我可以在那里设置一个断点然后调用 getAttributes.get("name") (通过调试器)不会导致溢出/调用它自己的 getter 但而是返回提供给我的复合组件的属性。

我猜这与支持组件和复合组件之间的耦合有关。当第一次调用 getter 时,没有给出它们之间的耦合,因此调用 getAttributes.get("name") 会导致调用我的支持组件的 getter,而后来调用不会调用它自己的 getter,而是获取提供给我的 comp 组件的属性。

有人知道如何解决这个问题吗? 提前谢谢。

【问题讨论】:

  • getAttributes()的代码呢,能分享一下吗?它在同一个支持 bean 中吗?
  • @cheffe:它只是继承自 UIComponent 类。 xstring,我冒昧地从问题中删除了[java] 和[ejb] 标签,因为这个问题根本与此无关,只会吸引像上面这样无用的 cmets。

标签: jsf jsf-2 composite-component


【解决方案1】:

UIComponent#getAttributes()是一张很特别的地图。在给定的键上,比如"foo",它首先将#{component.foo} 评估为ValueExpression,它隐式调用UIComponent#getFoo() 方法。另见the javadoc。这完全解释了无限循环。如果没有 getFoo() 方法,那么它只会继续查看“静态”映射(您可以通过覆盖 UIComponent#getValueExpression() 来控制它)。

您需要以不同的方式解决具体的功能需求。实际上,我很难理解您的具体功能要求,但我相信您实际上需要使用单独的 getter/setter 定义单独的属性,所有这些都正确委派给状态助手:

public String getLocalName() {
    return getStateHelper().eval("localName", getAttributes().get("name")); // Note: this thus defaults to #{cc.attrs.name} when not set before.
}

public void setLocalName(String localName) {
    return getStateHelper().put("localName", localName);
}

然后在复合实现中作为

<h:inputText value="#{cc.localName}" />

而不是

<h:inputText value="#{cc.attrs.name}" />

【讨论】:

  • 非常感谢您的帮助 BalusC。我的功能要求是在最终按下“保存”按钮时,在经过一些编辑后首先更新提供给我的 comp 组件的原始属性。在此之前,我需要使用该属性的副本以不更新我的模型。希望此解决方案有意义,或者您有针对此特定功能要求的更好解决方案吗?
  • 好的,那么上面的答案确实适用。但是,您应该将保存按钮的操作绑定到支持组件,例如 action="#{cc.save}",并通过它们的 getter 收集本地值,然后映射回原始属性,例如 getAttributes().put("name", getLocalName());。
  • 现在感谢您的帮助以及您向其他人提供的所有其他答案。非常尊重你的工作。如果我猜对了,你也是我们在这里经常使用的 Primefaces 背后的人之一......
  • 我不是 PrimeFaces 开发人员,而是 PrimeFaces 用户。然而,我是 OmniFaces 背后的人。
  • 当我现在尝试做一些 p:ajax 读取 Origin 属性时,我得到一个休眠异常:未能延迟初始化集合,没有会话或会话被关闭。
猜你喜欢
  • 2012-04-29
  • 2011-07-23
  • 2013-06-14
  • 1970-01-01
  • 2011-06-27
  • 2011-07-24
  • 2011-05-01
  • 2011-05-03
  • 2013-03-23
相关资源
最近更新 更多