XPages中用DataObject实现Bean加载文档项到Map时遇类未找到异常
问题排查与解决方案
核心原因
你遇到的javax.faces.FacesException无法创建Bean实例的问题,本质是Bean初始化阶段(构造函数或初始化逻辑)抛出了未捕获的异常,导致JSF容器中断了Bean的创建流程。注释掉setValue(item.getName(), item.getValueCustomData())后能正常显示,说明这行代码(或其依赖的Notes对象操作)是异常的触发点。
具体排查方向与解决步骤
调整初始化时机并添加异常处理
不要在Bean的构造函数中直接执行Notes文档读取、项操作这类可能抛出异常的逻辑。JSF构造函数中抛出未处理的NotesException会直接导致Bean创建失败。改用@PostConstruct注解的方法来完成数据初始化,同时必须捕获并处理NotesException:- 构造函数只做简单的成员变量初始化(比如初始化Map)
- 把读取Notes文档、填充Map的逻辑放到
@PostConstruct方法中,并包裹在try-catch块里,避免异常冒泡到JSF容器
验证Notes对象的有效性
- 确认初始化时能正确获取Notes Session、数据库、目标文档:比如当前用户是否有权限访问目标数据库/文档?目标视图是否存在?
- 操作
Item对象前先做非空判断:比如item != null && item.getName() != null,避免空指针异常;同时可跳过系统内置项(如以$开头的项)
检查
getValueCustomData()的实现
这个方法可能在处理特定类型的项(比如富文本、日期、附件)时抛出异常,或者返回了DataObject无法处理的类型。可以先打印item.getType()和value的值,排查是否有类型转换问题。
修正后的代码示例
import javax.annotation.PostConstruct; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped; import java.util.HashMap; import java.util.Map; import java.util.Vector; import lotus.domino.Document; import lotus.domino.Item; import lotus.domino.NotesException; import lotus.domino.Session; import com.ibm.xsp.extlib.util.ExtLibUtil; import com.ibm.xsp.model.DataObject; @ManagedBean(name = "Config") @SessionScoped public class ConfigBean implements DataObject { private Map<String, Object> dataMap = new HashMap<>(); public ConfigBean() { // 构造函数仅初始化基础变量 } @PostConstruct public void loadConfigData() { Session notesSession = null; Document configDoc = null; try { // 获取当前Notes会话与数据库 notesSession = ExtLibUtil.getCurrentSession(); configDoc = notesSession.getCurrentDatabase().getView("vwConfig").getFirstDocument(); if (configDoc != null) { Vector<?> items = configDoc.getItems(); for (Object obj : items) { Item item = (Item) obj; // 跳过系统项,只处理摘要项 if (item.isSummary() && !item.getName().startsWith("$")) { Object itemValue = item.getValueCustomData(); if (itemValue != null) { dataMap.put(item.getName(), itemValue); } } } } } catch (NotesException e) { // 记录日志或添加自定义异常处理逻辑,避免异常抛出到JSF容器 e.printStackTrace(); } finally { // 回收Notes对象,避免Domino内存泄漏 try { if (configDoc != null) configDoc.recycle(); if (notesSession != null) notesSession.recycle(); } catch (NotesException e) { e.printStackTrace(); } } } @Override public Object getValue(String key) { return dataMap.get(key); } @Override public void setValue(String key, Object value) { dataMap.put(key, value); } // 实现DataObject的其他必填方法 @Override public boolean isReadOnly(String key) { return false; } @Override public Class<?> getType(String key) { Object value = dataMap.get(key); return value != null ? value.getClass() : Object.class; } @Override public boolean exists(String key) { return dataMap.containsKey(key); } }
额外注意事项
- 务必回收Notes对象(Session、Document、Item等),避免Domino内存泄漏
- 如果是Session作用域的Bean,要考虑文档数据更新后的同步问题(比如添加手动刷新数据的方法)
内容的提问来源于stack exchange,提问作者Thomas Adrian
相关产品推荐
相关产品推荐

