gpt4 book ai didi

JSF 复合组件支持 bean EL 表达式作为必需属性的默认值失败,方法未知

转载 作者:行者123 更新时间:2023-12-02 05:36:40 24 4
gpt4 key购买 nike

我有一个 JSF 复合组件 util_primefaces:inplace_name,它需要一个“管理器”支持 bean,它在编辑实体的“名称”字段时执行持久性更新(使用 p:inplace):

<cc:interface>
<cc:attribute name="manager" type="com.example.web.AbstractManager" required="false" default="#{blockManager}"/>
<cc:attribute name="element" type="com.example.entity.Element" required="true"/>
<cc:attribute name="elid" required="true"/>
<cc:attribute name="update" required="false" default="@parent"/>
..
</cc:interface>

<cc:implementation>
..
<p:inplace id="#{cc.attrs.elid}" editor="true" emptyLabel="UNDEF" >
<p:ajax
event="save"
listener="#{cc.attrs.manager.onInplaceNameSaveEvent}"
process="@this #{cc.attrs.elid}-name"
update="#{cc.attrs.update}"
/>
<h:inputText id="#{cc.attrs.elid}-name" value="#{cc.attrs.element.name}"/>
..

例如 @ViewScoped @ManagedBean BlockManager 最终扩展了一个 AbstractManager,它有一个监听器方法:

public void onInplaceNameSaveEvent(AjaxBehaviorEvent ae).

[旁白:这里描述了不寻常的“elid”属性的原因,它在这个问题中没有进一步的作用:Primefaces p:inplace: How to more elegantly propagate the EL expression for entity to merge ]

当我调用传入显式 #{blockManager}(或 AbstractManager 的其他子类)的复合组件时,它工作正常:

<util_primefaces:inplace_name 
element="#{tenancy}"
elid="tenancy"
manager="#{blockManager}"
/>

但如果我不传入 #{blockManager},在执行就地编辑和保存时,我会收到一个错误,指出方法 onInplaceNameSaveEvent(AjaxBehaviorEvent) 未知:

<util_primefaces:inplace_name 
element="#{tenancy}"
elid="tenancy"
/>

错误是:

WARNING: Method not found: com.example.web.BlockManager@71396a88.onInplaceNameSaveEvent(javax.faces.event.AjaxBehaviorEvent)
javax.el.MethodNotFoundException: Method not found: com.example.web.BlockManager@71396a88.onInplaceNameSaveEvent(javax.faces.event.AjaxBehaviorEvent)
at com.sun.el.util.ReflectionUtil.getMethod(ReflectionUtil.java:155)

问:为什么在复合组件属性中使用 default="#{blockManager}"没有正确获取 backing bean?

最佳答案

根据 the documentation for the tag cc:attributedefault 的值必须评估为 java.lang.String

这就是为什么 #{blockManager} 表达式没有像您期望的那样工作,您只能为 String 属性设置默认值。

要查看会发生什么,您可以测试在标签库 (like showed here) 中注册以下函数:

public static String typeOf(Object o) {
return o == null ? null : o.getClass().toString();
}

并在这样的复合组件中使用它:

<ui:composition>
<cc:interface>
<cc:attribute name="param" type="java.lang.Integer" required="true"
default="1" />
</cc:interface>
<cc:implementation>
<h:outputText value="#{fnc:typeOf(cc.attrs.param)}" />
</cc:implementation>
</ui:composition>

现在,如果您在不指定 param 的情况下使用该组件,如下所示:

<my:comp />

... 它将输出 class java.lang.String,因为它使用 ValueExpression 的结果作为 default 属性,即字符串 “1”

当你指定参数时:

<my:comp param="1" />

... 它输出 class java.lang.Integer,因为现在它是通过强制转换为为 cc:attribute 指定的类型而产生的值。

关于JSF 复合组件支持 bean EL 表达式作为必需属性的默认值失败,方法未知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11596470/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com