配置文件的替代方案

Alternative for profile document

我正在关注 article,它告诉我们如何存储全局参数,配置文件文档如何用于经典 Notes 应用程序。我按照文章的步骤并根据必要的全局参数实现了 类,但是当我调用 javascript 对象的方法时,会发生以下错误。我有点困惑,因为在应用程序的其他地方调用相同的方法可以正常工作。下面是 javascript 对象的代码,作为文章中的示例实现。

脚本解释器错误,第 12 行,第 21 行:[TypeError] 在 'java.util.HashMap [Dynamic Java Wrapper, java.util.HashMap]'

类型的对象上调用方法 'getDbRH()' 时出错
var dbFotoConfig = { 

getDbFoto : function ( ) { 

    var cache = this. getCacheObject ( ) ; 

    var result = cache.get( "DbFoto" ) ; 

    if (result == null ) {

        // Here is where you would do @DBSomething or worse
        var visao:NotesView=database.getView("Configuracoes")
        var doc:NotesDocument=visao.getFirstDocument();
        if (doc!=null)
        {

            result=  [doc.getItemValueString("servidor_foto"),doc.getItemValueString("base_foto"),doc.getItemValueString("visao_foto")]
            cache.put("DbFoto",result)
             sessionScope.put ( "dbFotoConfig" ,cache )
        }
        else
        {

        cache.put("DbFoto",null)
         sessionScope.put ( "dbFotoConfig" ,null )
        }           

    } 

    return result ; 
} , 


    /* Here would be much more of these functions */ 


    /* Utility functions for cache management */ 

/* Retrieves the configuration object from a cache store. 
   There are many ways to do that */ 
getCacheObject : function ( ) { 
    // Consider carefully where to cache. Typical places 
    // are sessions or applications 
    var curCache = sessionScope. get ( "dbFotoConfig" ) ; 
    if (curCache == null ) { 
        curCache = new java. util. HashMap ( ) ; 
        sessionScope. put ( "dbFotoConfig" ,curCache ) ; 
    } 

    return curCache ;     
} , 

/* Resets the cache */ 
reset : function ( ) { 
    var curCache = new java. util. HashMap ( ) ; 
    sessionScope. put ( "dbFotoConfig" ,curCache ) ; 
} 
}
var dbRHConfig = {

getDbRH : function ( ) { 

var cache = this. getCacheObject ( ) ;

var result = cache. get ( "DbRH" ) ;

if (result == null ) {

    // Here is where you would do @DBSomething or worse
    var visao:NotesView=database.getView("Configuracoes")
    var doc:NotesDocument=visao.getFirstDocument();
    if (doc!=null)
    {

        result=[doc.getItemValueString("servidor_RH"),doc.getItemValueString("base_RH"),doc.getItemValueString("visao_RH")]
        cache.put("DbRH",result)
         sessionScope.put ( "dbRHConfig" ,cache )
    }
    else
    {

        cache.put("DbRH",null)
     sessionScope.put ( "dbRHConfig" ,null )
    }


} 

return result ; 
} , 


/* Here would be much more of these functions */ 


/* Utility functions for cache management */ 

/* Retrieves the configuration object from a cache store. 
There are many ways to do that */ 
getCacheObject : function ( ) { 
// Consider carefully where to cache. Typical places 
// are sessions or applications 
var curCache = sessionScope. get ( "dbRHConfig" ) ; 
if (curCache == null ) { 
    curCache = new java. util. HashMap ( ) ; 
    sessionScope. put ( "dbRHConfig" ,curCache ) ; 
} 

return curCache ;     
} , 

/* Resets the cache */ 
reset : function ( ) { 
var curCache = new java. util. HashMap ( ) ; 
sessionScope. put ( "dbRHConfig" ,curCache ) ; 
} 
}

我的首选选项是创建一个普通文档,保存它,然后调用 setUniversalID() 使用 session.evaluate("@Password(\"whateverYouWant\")") 将其更改为自定义文档。 @Password 将值散列为 32 个字符的十六进制字符串(即有效的 UNID)。这使您可以使用 Database.getDocumentByUnid() 轻松检索文档(普通文档,从而避免 Profile 文档的缓存问题),这是访问文档的最快方法之一。如果你想避免每次都计算它,你可以将 "UNID" 存储在 applicationScope 变量中。

拜托,拜托,不要那样做。忘掉 SSJS 并尽可能多地使用 XPages:一个 IBM Domino 风格的 JSF 框架实现。

首先,您需要确定您希望配置保留多长时间,以及它是否对每个用户都相同。

如果每次使用都相同,您可以做的最好的事情就是将它存储在应用程序范围 bean 中。应用程序范围与每个用户共享,实例化一次并持续整个应用程序的生命周期。

session 作用域 bean 与当前用户保持一致,并且仅对当前用户可见。

托管 bean 的生命,是的,由框架管理。该框架负责在应用程序中的任何地方引用它时对其进行实例化。它通过您在 XPage 应用程序的 faces-config.xml 文档中配置它时决定的变量名称进行分发。

<managed-bean>
    <managed-bean-name>app</managed-bean-name>
    <managed-bean-class>demo.bean.ApplicationBean
    </managed-bean-class>
    <managed-bean-scope>application</managed-bean-scope>
</managed-bean>

managed-bean-name 声明了您的 bean 可用的变量名。 managed-bean-scope 表示 bean 的寿命。

现在你需要做的是在包demo.bean下创建一个Javaclass,名称为ApplicationBean(这就是上面示例中的内容,您可以随意命名)。 从你命名变量的方式来看,在我看来你需要更多的应用程序范围的 bean 而不是会话 bean。因此,为了便于交流,我编写了一个示例,说明根据您在上面发布的代码,应用程序 bean 对您来说可能是什么样子

package demo.bean;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import javax.faces.FacesException;

import lotus.domino.Document;
import lotus.domino.NotesException;
import lotus.domino.View;

import com.ibm.xsp.model.domino.DominoUtils;

public class ApplicationBean implements Serializable {

    private static final long serialVersionUID = 1L;

    // Just a way to do it without repeating the same lines over and over
    private static final String[] CONFIG_FIELD_PREFIXES = { "servidor", "base", "visao" };

    private Map<String, String> dbFoto;
    private Map<String, String> dbRh;

    public Map<String, String> getDbFoto() {
        if (dbFoto == null) {
            loadConfig();
        }

        return dbFoto;
    }

    public Map<String, String> getDbRh() {
        if (dbRh == null) {
            loadConfig();
        }

        return dbRh;
    }

    private void loadConfig() {
        dbFoto = new HashMap<String, String>();
        dbRh = new HashMap<String, String>();

        try {
            View vw = DominoUtils.getCurrentDatabase().getView("Configuracoes");
            Document doc = vw.getFirstDocument();

            if (doc != null) {
                for (String fieldName : CONFIG_FIELD_PREFIXES) {
                    dbFoto.put(fieldName, doc.getItemValueString(fieldName + "_foto"));
                    dbRh.put(fieldName, doc.getItemValueString(fieldName + "_RH"));
                }
            }
        } catch (NotesException e) {
            throw new FacesException(e.getMessage(), e);
        }
    }

    public void reset() {
        dbFoto = null;
        dbRh = null;
    }

}

那里有一些概念。希望我没有给你太多。但简要解释一下:首先,bean 大部分时间都在延迟加载中工作,这意味着您不会在创建它们时预加载数据,而是让 class 在外部源调用其方法时填充。第一次调用该方法时,它会加载并缓存数据(您不必担心它的持久性,因为请记住,这是由框架保证的,它的生命周期在 faces-config.xml 中确定)。第二次调用该方法时,它将提供缓存数据(您在 class 开头声明的 Map 对象中看到的内容)。考虑到您从同一个地方加载 2 个数据库配置这一事实,一次加载两个数据库配置比在不同时间延迟加载它们的成本更低 - 这就是我编写私有方法 loadConfig.[=22 的原因=]

现在发生的是配置存储在地图中,并且由于 EL 表达式,您可以以简洁的方式从此类地图中读取数据。 如果您使用以下代码创建 XPage,您将看到页面上的所有内容都活跃起来:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">

    <xp:text value="#{app.dbFoto.servidore} #{app.dbFoto.base} #{app.dbFoto.visao}" />

    <xp:text value="#{app.dbHr.servidore} #{app.dbHr.base} #{app.dbHr.visao}" />

    <xp:button id="button1" value="reset">
        <xp:eventHandler event="onclick" submit="true"
            refreshMode="complete" action="#{app.reset}" />
    </xp:button>

</xp:view>

app 是我们的 bean 名称 dbFoto / dbHr 是我们对 Map<String, String> getDbFoto( / Map<String, String> getDbHr( 的调用(get 被删除并且第一个字母小写,那是要遵守的约定),每个名称都是访问映射值的键。

我还提供了一个帮助方法来清除配置以备不时之需:reset()。它只是使 2 个变量无效,因此在第一次再次询问它们时将再次获取这些变量。