【问题标题】:ViewScope variables becoming null, keepsessionalive not working?ViewScope 变量变为空,keepsessionalive 不起作用?
【发布时间】:2018-07-03 15:26:14
【问题描述】:

Lotus Notes 9.0.1 中的 View Scope 变量有问题。

用户报告我的应用程序出现错误,其中视图范围变量可能在页面加载时变为空 - 该变量是一个数组,自定义控件中标签的计算值试图访问该数组,从而导致运行时异常。该变量应通过库方法加载,该方法由手风琴窗格的计算标题脚本调用,该脚本包含尝试读取它的自定义控件。

就我测试而言,整个事情每次都有效,但应用程序的一位用户报告了运行时异常。进一步调查后,我验证了可以通过构建应用程序并单击打开页面上的某个链接来重现该错误。阅读这些问题和服务器日志,我了解到这可能是由范围变量丢失引起的,可能是由会话超时触发的,但我们的应用程序应该能够使用 XPages 扩展库中的 keepsessionalive 控件来处理会话超时 -但它似乎没有按预期工作。

我想要一些关于问题的其他可能原因/触发器的输入(到目前为止,我无法重现该问题,因为它是用户报告的),以及使会话长时间保持活动状态的替代方法不会丢失作用域变量。

代码如下:

手风琴标题(变量加载的地方,其他标题类似):

    viewScope.contadorParecer=carregaContadoresParecer(); //Where the variable should be loaded
    if(viewScope.contadorParecer.total>0)
    return "Pareceres ("+viewScope.contadorParecer.total+")";
    else
    return "Pareceres"

Script library method (similar code for the others):

    function carregaContadoresProposta() {
        try {
            contadoresProposta = {};
            try {
                if (arguments[0])
                    var totalizar = arguments[0];
                else
                    var totalizar = compositeData.totalizarUnidade;
            } catch (e) {
                var totalizar = false;
            }

            if (!totalizar) {
                var strView = "vw_proposta_contador";
                var filtro = sessionScope.usuarioLogado.nome;
            } else {
                var strView = "vw_proposta_unidade_contador";
                var filtro = sessionScope.usuarioLogado.fk_entidade_funcional;
            }

            //cria navegador
            var nav: NotesViewNavigator = database.getView(strView).createViewNavFromCategory(filtro);
            var entry: NotesViewEntry = nav.getFirst();
            var total = 0;
            while (entry != null) {
                var categoria = entry.getColumnValues()[1];
                categoria = @UpperCase(categoria);
                contadoresProposta[categoria] = entry.getColumnValues()[entry.getColumnValues().size() - 1];
                if (!categoria.isEmpty()) 
                total += contadoresProposta[categoria];
                var tmpentry: NotesViewEntry = nav.getNextCategory();
                entry.recycle();
                entry = tmpentry;
            }
            contadoresProposta["total"] = total;

            return contadoresProposta.clone();
        } catch (e) {
            printError(e, "carregaContadoresProposta", "Script Library ContextualProposta");
        }
    }

自定义控件(contadorAcompanhamamento、contadorProposta 和 contadorParecer 在被读取之前变为 null):

var label=item.split("|")[0];
label=label.indexOf("{")!=-1?label.split("{")[0]:label;

var parecer=compositeData.parecer[0];
var acompanhamento=compositeData.acompanhamento;

if(!parecer){
    if(acompanhamento){
        var total=viewScope.contadorAcompanhamento[@UpperCase(label)];
    }else{
        var total=viewScope.contadorProposta[@UpperCase(label)];
    }
}else{
    var total=viewScope.contadorParecer[@UpperCase(label)]; 
}

if(total!=undefined)
    return label+" ("+ total +")"
else
    return label;

运行时错误:

Error while executing JavaScript computed expression
Script interpreter error, line=11, col=37: 'viewScope.contadorProposta' is null and cannot be accessed as an array

在用户的服务器日志中发现的第一个错误:(可能是由 scriptlibrary 中设置的 tmpEntry 引起的) 调用方法NotesViewNavigator.getNextCategory()发生异常

【问题讨论】:

  • 听起来用户告诉你的不是整个过程,并且缺少关键信息。当您能够解决问题时,您没有解释原因是什么以及重现的步骤。另外,服务器日志中的错误是否相关?您提到keepSessionAlive 组件,但不确认您或用户是否离开浏览器选项卡 - 以及浏览器中应用程序的任何其他选项卡 - 在一段时间内处于非活动状态。如果不是,则会话超时无关紧要。
  • 我认为服务器日志不相关。我认为这是变量被清空的结果,不太可能是原因,因为有几个变量变为空,并且并非所有变量都调用 getNextCategory 来填充。我把它包括在内,因为我是一个初学者,我想我可能会遗漏一些东西。是的,除了在浏览器上打印的运行时错误之外,用户没有提供太多关于错误的信息,并且错误发生在从一个选项卡到另一个选项卡(部分刷新)时。重现起来很痛苦,但页面可能已经有一段时间不活动了。
  • " 我验证了该错误可以通过构建应用程序并单击打开页面上的某个链接来重现。" -> 这是否意味着您在使用它的同时构建应用程序?
  • 是的,乌梅里。我知道这可能不是问题的实际原因,构建应用程序只会导致变量左右丢弃。我只是认为它是一个重要的信息(以及我目前用来测试应用程序行为的方式),因为它会创建与用户看到的完全相同的运行时错误屏幕。
  • 我的建议:停止在 viewScope 中使用带有麻烦的初始化脚本的专有属性,并使用“view”范围实现托管 bean。这将处理值初始化的所有问题。

标签: xpages lotus-notes lotus-domino xpages-ssjs xpages-extlib


【解决方案1】:

正如保罗所解释的:您可能需要进行长时间的调查。但是,您面临的真正问题是使用范围变量的不幸方法。会话和应用程序范围会超时和到期,因此切勿将它们视为理所当然并检查它们是否存在。因此,您无需在不相关的位置播种值,而是在脚本函数中检查它们是否存在。

类似的东西(在 SSJS 脚本库中):

  var carregaContadoresParecer = {
      storage : null,
      total : function() {
          if (storage === null) {
             storage = populateStorage();
          }
          return storage.total;
      },
      contadorParecer : function(whatSearch) {
          if (storage === null) {
             storage = populateStorage();
          }
              // your code here
      }

  } 

沿着这些思路。然后你可以使用carregaContadoresParecer.total()carregaContadoresParecer.contadorParecer('someLabel');

因此,您不会将函数存储在作用域中,而是将函数存储在 JavaLib 中,并且仅将值存储在作用域中并检查该值是否存在。我会使用托管 bean,但那是因为我对 Java 很熟悉 - 可能不适合您。

【讨论】:

    【解决方案2】:

    如果用户在应用程序中为不同的页面打开了很多选项卡,则可以填充服务器端的页面映射(视图,即viewScope)并删除以前使用的页面。这在 Persistence 选项卡上的 Xsp Properties 中处理。周围有各种会议幻灯片,掌握 XPages 和 XPages 便携式命令指南书籍也对此进行了介绍。

    这可能是原因,但需要用户提供进一步的信息来确认或反驳。

    【讨论】:

      【解决方案3】:

      viewScope 变量“contadorProposta”的初始化在哪里?你确定它已经初始化了吗?当用户重新加载页面时,viewScope 会丢失 - 有可能吗?

      【讨论】:

      • 手风琴容器以同样的方式初始化 'contadorParecer'、'contadorProposta' 和 'contadorAcompanhamento',通过调用脚本库中的 'carregaContadores...' 函数,类似于 carregaContadoresProposta。这三个都变成了null。不确定某些重新加载情况是否会导致 viewscope 丢失,但无论哪种方式都应该在页面加载时重新计算它——我什至添加了一个调用,以在读取它们的脚本上加载所有三个变量的值(我我不完全确定这是否有效 - 我无法以任何方式重现错误)
      猜你喜欢
      • 2016-07-25
      • 1970-01-01
      • 2021-08-04
      • 2018-12-31
      • 2011-05-12
      • 2012-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多