如何在XPage中存储IBM Notes数据库对象变量并后续访问
问题分析与解决方案
你遇到的这个500错误,核心原因是Domino的原生后端对象(比如NotesDatabase、NotesDocument这类)根本不能直接存到任何Scope里,不管是viewScope、sessionScope还是applicationScope都不行。
这些Notes对象是基于本地JNI调用实现的,不支持Java序列化,但Scope的存储机制依赖序列化来持久化对象。你在onPageLoad里能正常用db_rooms是因为它是当前请求周期内的活跃对象,但一旦把它放进Scope,再读取时就会因为无法反序列化而触发错误。
正确的处理思路
1. 存储关键参数,每次使用时重新获取数据库(推荐)
别存数据库对象本身,而是把服务器名和数据库路径这两个关键信息存到Scope里,之后每次需要用数据库时,再通过session重新构建对象:
// 在onPageLoad里先存必要的参数 var serverName = session.createName(doc_ProfileConfig.getItemValueString("ServerNA")).getCommon(); var filePath = doc_ProfileConfig.getItemValueString("FilePathTX"); viewScope.put("ResroomServer", serverName); viewScope.put("ResroomFilePath", filePath); // 后续需要调用数据库时,再重新获取 var server = viewScope.get("ResroomServer"); var path = viewScope.get("ResroomFilePath"); var db:NotesDatabase = session.getDatabase(server, path); // 记得加个有效性检查 if (db != null && db.isOpen()) { // 这里写你的业务逻辑 }
这种方式虽然看起来重复,但能保证每次拿到的都是有效的数据库对象,也是Domino开发里的标准做法。
2. 关于applicationScope的疑问
绝对不建议把NotesDatabase存到applicationScope里,理由有两个:
- 同样会遇到序列化问题,读取时照样报错;
- applicationScope是全局共享的,数据库对象持有连接资源,全局存储容易导致资源泄漏,而且多用户并发访问时还可能出现线程安全问题,风险很高。
小技巧:封装复用逻辑
如果需要在多个地方用到这个数据库,可以把获取逻辑封装成一个函数,减少重复代码:
function getResroomDb() { var server = viewScope.get("ResroomServer"); var path = viewScope.get("ResroomFilePath"); var db = session.getDatabase(server, path); return (db != null && db.isOpen()) ? db : null; } // 用的时候直接调用就行 var db = getResroomDb(); if (db) { // 执行你的操作 }
内容的提问来源于stack exchange,提问作者user9108165
相关产品推荐
相关产品推荐

