JSF 2.2:将 bean 属性作为 ValueExpression 传递给复合
JSF 2.2: Passing bean attribute as ValueExpression to composite
我想将 non-managed (non-String) object 作为属性传递给动态添加的复合组件,并让它在 session 之后继续存在。
JSF 2.2 ViewDeclarationLanguage#createComponent
处理复合组件的动态 non-string 属性值的方式不同于旧的 Mojarra 依赖代码 (Application#createComponent
)。我找不到完全适用于 JSF 2.2 技术的方法,但可能是我。
[我正在尝试通过转换为 MyFaces 来移除 Mojarra 依赖项(并解决其他一些 Mojarra 问题)。我正在使用 JSF 2.2、CDI Weld 2.2.16、Tomcat v8.0]
我正在以编程方式实例化不同的复合组件(注意 bean 属性):
<cc:interface>
<cc:attribute name="bean" required="true" type="com.aadhoc.cvc.spikes.extensionsapproach.ExtensionBeanInterface"/>
</cc:interface>
<cc:implementation>
<h:panelGrid columns="2">
<h:outputText value="Title:"/>
<h:inputText value="#{cc.attrs.bean.title}"/>
</h:panelGrid>
</cc:implementation>
在旧的 Mojarra 依赖方法中,我实例化了 non-managed bean object,并将其作为属性直接添加到复合组件中,效果很好(我使用的是@BalusC 的很棒但来自 OmniFaces Component#includeCompositeComponent
):
的依赖于 Mojarra 的示例代码
ExtensionBeanInterface bean = Class.forName(className).newInstance();
attributes = new HashMap<String, Object>();
attributes.put("bean", bean); // Using bean object itself
[..]
UIComponent composite = application.createComponent(context, resource);
composite.getAttributes().putAll(attributes);
[..]
在 JSF 2.2 中,我发现我必须直接传递字符串 ValueExpression
而不是我的 bean
object。我目前正在使用这种技术,但不能完全正确:
FacesContext context = FacesContext.getCurrentInstance();
ELContext elContext = context.getELContext();
ValueExpression beanValExp = context.getApplication().getExpressionFactory()
.createValueExpression(elContext, "#{customBeanVE}", ExtensionBeanInterface.class);
beanValExp.setValue(elContext, bean);
String beanValExpStr = beanValExp.getExpressionString();
attributes = new HashMap<String, Object>();
attributes.put("bean", beanValExpStr); // Using VE instead of bean object
UIComponent composite = context.getApplication().getViewHandler()
.getViewDeclarationLanguage(context, context.getViewRoot().getViewId())
.createComponent(context, taglibURI, tagName, attributes);
[..]
这在第一个 "add composite" 上效果很好,但在提交任何后续表单时,我得到:
/resources/com/aadhoc/cvc/spikes/extensionsapproach/components/House.xhtml
@16,49 value="#{cc.attrs.bean.title}": Target Unreachable, 'bean'
returned null
我已验证组合的 required 和 type 属性工作正常,并且 #{cc.attrs.bean.title}
最初显示了 bean 的标题。我通过静态使用刷新工作正常的复合组件进行了验证。
怎么回事,我怎样才能移交 bean object 以便它与复合体一起在 session 中存活?
我在 Mojarra 的这个工作很棒。我可以将 bean 对象放在属性值中,一切都很棒。尝试 MyFaces,我需要 change/update 我的方法,现在我需要使用 EL 字符串而不是直接对象引用。
由于所有人都只是将 bean 对象放入属性 Map 中,所以我想要一个神奇而优雅的地方来放置 bean 对象并让它们存活下来。我本可以将它们放入 "global" 会话映射(像这样:How to save an object into JSF Session),但它不够干净。然后我将它们放入我的一个主要会话状态 bean (modelerBean) 中,它是正确的。这就是我保存 bean 的方式,以及我如何使用 EL 字符串指向它的方式。无需创建 ValueExpression 或 MethodExpression 对象或注册特殊映射。这种与 JSF 2.2 兼容的方法在 Mojarra 和 MyFaces 中对我都有效。
public void onAdd(ActionEvent ev) {
[..]
ChosenBean chosenBean = new ChosenBean();
chosenBean.setComponentId(id);
chosenBean.setBean(bean);
modelerBean.addChosen(chosenBean);
[..]
String el = "#{modelerBean.getChosen('"+id+"').bean}"
attributes.put(MODELER_EXTENSION_BEAN_ATTRIBUTE_NAME, el);
[..]
我在阅读@BalusC 的 post 后决定这样做:How do I get and set an object in session scope in JSF?
请注意,我对@BalusC 的两种 "add composites dynamically" 方法 (How to programmatically or dynamically create a composite component in JSF 2) 的经验是,如果可以的话,您绝对应该使用 JSF 2.2 方法。如果您不在 JSF 2.2 中,旧的 Mojarra 方法确实有效。一旦我修改了我的代码以使 JSF 2.2 方法起作用,旧的 Mojarra 方法就会以奇怪的方式崩溃。
我想将 non-managed (non-String) object 作为属性传递给动态添加的复合组件,并让它在 session 之后继续存在。
JSF 2.2 ViewDeclarationLanguage#createComponent
处理复合组件的动态 non-string 属性值的方式不同于旧的 Mojarra 依赖代码 (Application#createComponent
)。我找不到完全适用于 JSF 2.2 技术的方法,但可能是我。
[我正在尝试通过转换为 MyFaces 来移除 Mojarra 依赖项(并解决其他一些 Mojarra 问题)。我正在使用 JSF 2.2、CDI Weld 2.2.16、Tomcat v8.0]
我正在以编程方式实例化不同的复合组件(注意 bean 属性):
<cc:interface>
<cc:attribute name="bean" required="true" type="com.aadhoc.cvc.spikes.extensionsapproach.ExtensionBeanInterface"/>
</cc:interface>
<cc:implementation>
<h:panelGrid columns="2">
<h:outputText value="Title:"/>
<h:inputText value="#{cc.attrs.bean.title}"/>
</h:panelGrid>
</cc:implementation>
在旧的 Mojarra 依赖方法中,我实例化了 non-managed bean object,并将其作为属性直接添加到复合组件中,效果很好(我使用的是@BalusC 的很棒但来自 OmniFaces Component#includeCompositeComponent
):
ExtensionBeanInterface bean = Class.forName(className).newInstance();
attributes = new HashMap<String, Object>();
attributes.put("bean", bean); // Using bean object itself
[..]
UIComponent composite = application.createComponent(context, resource);
composite.getAttributes().putAll(attributes);
[..]
在 JSF 2.2 中,我发现我必须直接传递字符串 ValueExpression
而不是我的 bean
object。我目前正在使用这种技术,但不能完全正确:
FacesContext context = FacesContext.getCurrentInstance();
ELContext elContext = context.getELContext();
ValueExpression beanValExp = context.getApplication().getExpressionFactory()
.createValueExpression(elContext, "#{customBeanVE}", ExtensionBeanInterface.class);
beanValExp.setValue(elContext, bean);
String beanValExpStr = beanValExp.getExpressionString();
attributes = new HashMap<String, Object>();
attributes.put("bean", beanValExpStr); // Using VE instead of bean object
UIComponent composite = context.getApplication().getViewHandler()
.getViewDeclarationLanguage(context, context.getViewRoot().getViewId())
.createComponent(context, taglibURI, tagName, attributes);
[..]
这在第一个 "add composite" 上效果很好,但在提交任何后续表单时,我得到:
/resources/com/aadhoc/cvc/spikes/extensionsapproach/components/House.xhtml @16,49 value="#{cc.attrs.bean.title}": Target Unreachable, 'bean' returned null
我已验证组合的 required 和 type 属性工作正常,并且 #{cc.attrs.bean.title}
最初显示了 bean 的标题。我通过静态使用刷新工作正常的复合组件进行了验证。
怎么回事,我怎样才能移交 bean object 以便它与复合体一起在 session 中存活?
我在 Mojarra 的这个工作很棒。我可以将 bean 对象放在属性值中,一切都很棒。尝试 MyFaces,我需要 change/update 我的方法,现在我需要使用 EL 字符串而不是直接对象引用。
由于所有人都只是将 bean 对象放入属性 Map 中,所以我想要一个神奇而优雅的地方来放置 bean 对象并让它们存活下来。我本可以将它们放入 "global" 会话映射(像这样:How to save an object into JSF Session),但它不够干净。然后我将它们放入我的一个主要会话状态 bean (modelerBean) 中,它是正确的。这就是我保存 bean 的方式,以及我如何使用 EL 字符串指向它的方式。无需创建 ValueExpression 或 MethodExpression 对象或注册特殊映射。这种与 JSF 2.2 兼容的方法在 Mojarra 和 MyFaces 中对我都有效。
public void onAdd(ActionEvent ev) {
[..]
ChosenBean chosenBean = new ChosenBean();
chosenBean.setComponentId(id);
chosenBean.setBean(bean);
modelerBean.addChosen(chosenBean);
[..]
String el = "#{modelerBean.getChosen('"+id+"').bean}"
attributes.put(MODELER_EXTENSION_BEAN_ATTRIBUTE_NAME, el);
[..]
我在阅读@BalusC 的 post 后决定这样做:How do I get and set an object in session scope in JSF?
请注意,我对@BalusC 的两种 "add composites dynamically" 方法 (How to programmatically or dynamically create a composite component in JSF 2) 的经验是,如果可以的话,您绝对应该使用 JSF 2.2 方法。如果您不在 JSF 2.2 中,旧的 Mojarra 方法确实有效。一旦我修改了我的代码以使 JSF 2.2 方法起作用,旧的 Mojarra 方法就会以奇怪的方式崩溃。