如何从java类中的托管bean访问属性值?

时间:2017-05-11 11:38:45

标签: java xpages

我有想法为会话设置全局属性,例如"神模式"因此,在会话期间,一个人可以看到超过平均值(仅用于开发目的),例如

<managed-bean>
        <managed-bean-name>appBean</managed-bean-name>
        <managed-bean-class>se.corp.app.package.ApplicationBean</managed-bean-class>
        <managed-bean-scope>session</managed-bean-scope>
        <managed-property>
            <property-name>godmode</property-name>
            <value>true</value>
            <property-class>java.lang.Boolean</property-class>
        </managed-property>
    </managed-bean>

但是如何从另一个java类中访问属性集?

5 个答案:

答案 0 :(得分:1)

将一个getInstance()方法添加到ApplicationBean类:

public static ApplicationBean get() {
    return (ApplicationBean) resolveVariable("appBean");
}

我正在使用实用程序方法来解析bean变量。此方法是新扩展库的一部分,如ExtLibUtil.resolveVariable(name),可在此处获取:

public static Object resolveVariable(String variable) {
    return FacesContext.getCurrentInstance().getApplication().getVariableResolver().resolveVariable(FacesContext.getCurrentInstance(), variable);
}

然后,您可以从另一个类访问bean:

ApplicationBean appBean = ApplicationBean.get();

然后,您可以访问ApplicationBean中的所有公共属性和方法。

答案 1 :(得分:1)

你可以采取两种方式:一种是简单的,另一种更符合一般的JSF理念。换句话说,这是技术原则的个人诚信问题:D

简单的就是Per Henrik Lausten所说明的那个。然而,它在某种程度上存在缺陷。它并非真正环境中立/不可知。它并不意味着它是一个问题,但如果你想重新分配你的bean,你就会被强迫,并且迫使你,你的实现者,去你选择的bean名称 - 例如的 appBean

现在我不想过于复杂化,但更灵活的方法如下:

 <managed-bean>
      <managed-bean-name>appBean</managed-bean-name>
      <managed-bean-class>bean.ApplicationBean</managed-bean-class>
      <managed-bean-scope>session</managed-bean-scope>
      <managed-property>
           <property-name>name</property-name>
           <value>appBean</value>
      </managed-property>
 </managed-bean>

豆子:

public class ApplicationBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private static final String DEFAULT_NAME = "appBean";

    private String name;
    private boolean godMode;

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

    public void setGodMode(boolean godMode) {
        this.godMode = godMode;
    }

    public boolean isGodMode() {
        return godMode;
    }

    // Your other logic here

    public static ApplicationBean getInstance(FacesContext facesContext) {
        return (ApplicationBean) Helper.resolveVariable(facesContext, name != null ? name : DEFAULT_NAME);
    }

}

通过上述方法,bean可以部署在任何地方,如果必要,您可以定义一个不同的名称 - managed-bean-name,并且属性值必须匹配。否则,在设置managed-bean-name时,省略faces-config.xml中的name属性,与DEFAULT_NAME java类属性中显示的完全相同。

&#34;哲学&#34;相反,它是利用属性注入的方式。这一切都取决于你发现自己需要在所有bean中使用特定bean的频率。但请先看一下示例:

 <managed-bean>
      <managed-bean-name>appBean</managed-bean-name>
      <managed-bean-class>bean.ApplicationBean</managed-bean-class>
      <managed-bean-scope>session</managed-bean-scope>
      <managed-property>
           <property-name>godMode</property-name>
           <value>true</value>
                <property-class>java.lang.Boolean</property-class>
      </managed-property>
 </managed-bean>

 <managed-bean>
      <managed-bean-name>myOtherBean</managed-bean-name>
      <managed-bean-class>bean.MyOtherBean</managed-bean-class>
      <managed-bean-scope>view</managed-bean-scope>
      <managed-property>
           <property-name>app</property-name>
           <value>#{appBean}</value>
      </managed-property>
 </managed-bean>

另一个bean类:

public class MyOtherBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private ApplicationBean app;

    public void setApp(ApplicationBean app) {
        this.app = app;
    }

    public void doSomething() {
        // App is already here
        // no need to resolve it
        if (app.isGodMode()) {
            //do something;
        }
    }
}

我个人使用这两种方法,但我更喜欢这种方法。虽然有一个问题:您只能注入共享相同范围的bean,或者比注入它们的bean的范围更长。

app进入会话:是

会议进入视图:是

查看应用:否

请求查看:否

答案 2 :(得分:0)

所有托管bean,dataContext,数据源等都分配了一个引用,并且可用于托管bean等的生命周期。因此,如果dominoDocument具有变量名称&#34; myXPageDocument&#34;在XPage中定义,您可以使用&#34; myXPageDocument&#34;整个XPage中的标识符或插入XPage的任何自定义控件或从XPage调用的代码,以访问它。 (如果使用相同的变量名,您可能只得到&#34;最近的&#34;一个。)对于托管bean也是如此。如果你有一个viewScoped bean,XPage中的任何地方或插入XPage的自定义控件或从XPage调用的代码,你都可以访问它。

要访问其中任何一项,只需将变量名称传递给ExtLibUtil.resolve(appBean)即可。我认为,自ExtLib 9.0.1 v15或Domino 9.0.1 FP8以来,它只需要一个参数即变量名。这将调用VariableResolver,它访问所有隐式对象(bean,session等)和范围,直到找到传入变量名称的内容。

答案 3 :(得分:0)

我解释了你的问题与Per和Paul不同(Hi Per,嗨Paul,好久不见!)我认为你希望能够访问XPage中的托管Bean。

您可以借助表达式语言访问托管bean的任何属性。 IBM提供的文档很少,但它非常棒,可以帮助您将代码保留在应有的位置,即在Java类中。这是表达语言的文档:

https://docs.oracle.com/javaee/6/tutorial/doc/gjddd.html

在faces-config

中配置了托管bean
<managed-bean>
<managed-bean-name>TableOfContents</managed-bean-name>
<managed-bean-class>ch.magerman.zhpedia.tableofcontents.TableOfContents</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>

然后,您可以通过引用其名称

来访问XPage中的方法

e.g。

<xp:view
    xmlns:xp="http://www.ibm.com/xsp/core"
    xmlns:xc="http://www.ibm.com/xsp/custom"
    style="display:block;"
    beforePageLoad="#{TableOfContents.beforePageLoad}">

或其值:

<xp:repeat
    id="repeatfirstlevelnodes"
    rows="200"
    value="#{TableOfContents.root.children}"
    var="firstlevelnode"
    styleClass="NavLeft">

一个问题是资本化。在这个例子中,我的.root的getter在Java中看起来像这样:

public Node getRoot() {
    return rootNode;
}

要访问它,您需要删除'get'前缀并将大写R更改为小写r。

我希望这有帮助!

答案 4 :(得分:0)

嗯,所有答案(还)都复制了你在问题中引入的同样错误:通过faces-config设置属性所有用户都将进入神模式......

我的两分钱:出于您的目的,我们在数据库ACL中使用名为“Debug”的角色。但“GodMode”会做得很好。您可以在代码中的任何位置询问用户的ACL角色并检查调试角色。典型用例是显示/隐藏有助于调试/开发的组件。

https://lostinxpages.com/2014/01/06/finding-user-roles-in-xpages/