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

How can I access property value from a managed bean in a java class?

我想为 session 设置全局 属性 例如"god-mode" 所以在 session 期间,一个人可以看到比平均水平更多的东西(仅用于开发目的),例如

<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 class 中访问 属性 集?

将 getInstance() 方法添加到您的 ApplicationBean class:

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);
}

然后您可以像这样从另一个 class 访问该 bean:

ApplicationBean appBean = ApplicationBean.get();

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

所有托管 bean、dataContext、数据源等都分配了一个引用,该引用可用于托管 bean 等的生命周期。因此,如果在 XPage 中定义了变量名称为 "myXPageDocument" 的 dominoDocument ,您可以在整个 XPage 或插入 XPage 的任何自定义控件或从 XPage 调用的代码中使用该 "myXPageDocument" 标识符来访问它。 (如果使用相同的变量名,您可能只得到 "nearest" 一个。)托管 bean 也一样。如果您有 viewScoped bean,在 XPage 或插入 XPage 的自定义控件或从 XPage 调用的代码中的任何位置,您都可以访问它。

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

我对您的问题的解释与 Per 和 Paul 的不同(您好 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>

然后您可以通过引用它的名称在 XPages 中访问它的方法

例如

<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">

一个问题是大写。在这个例子中,我的 getter for .root 在 Java:

中看起来像这样
public Node getRoot() {
    return rootNode;
}

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

希望对您有所帮助!

您可以采用两种方法:一种简单,另一种更符合一般的 JSF 哲学。换句话说,这是技术原则的个人诚信问题:D

最简单的是 Per Henrik Lausten 的插图。然而,它在某种程度上是有缺陷的。这不是真正的环境 neutral/agnostic。这并不意味着这是一个问题,但如果你想重新分配你的 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 并且 属性 值必须匹配.否则,您在 faces-config.xml 中省略名称 属性,同时将 managed-bean-name 设置为与在 DEFAULT_NAME java class 属性.

"philosophical" 方法是利用属性注入。这完全取决于您发现自己在所有 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 class:

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 作用域更长的 bean。

应用进入会话:是

会话可见:是

查看应用程序:否

请求进入视图:否

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

我的两分钱:为了您的目的,我们在数据库 ACL 中使用名为 "Debug" 的角色。但是 "GodMode" 就可以了。您可以在代码中的任何位置询问用户的 ACL 角色并检查调试角色。典型用例是 show/hide 组件帮助 debug/development。

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