GWT项目遇UmbrellaException未捕获错误,无法显示问题答案
问题分析与解决方案
从你的描述和代码来看,点击问题后答案表格不显示,结合技术栈(GWT 2.8.0 + MapDB 1.0.9 + Eclipse Mars/Java7),我整理了几个最可能的原因和对应的修复步骤:
1. CellTable数据管理冲突(最可能导致表格不显示)
你的代码里同时混用了ListDataProvider和手动调用setRowCount()/setRowData(),这两种方式是互斥的:
- ListDataProvider会自动监听列表变化并更新CellTable
- 手动调用
setRowData()会覆盖DataProvider的管理逻辑,导致数据不同步,表格无法渲染
修复代码:
删掉onSuccess方法末尾的这两行:
questionsTable.setRowCount(response.size(), true); questionsTable.setRowData(0, response);
你已经通过dataProvider.getList().add(risposta)把数据添加到了DataProvider的列表中,DataProvider会自动处理CellTable的行数据渲染。
2. LinkList索引越界异常(可能导致代码执行中断)
不管是问题Grid还是答案表格里,你都直接调用getLinkList().get(0)到get(3),如果任何一个Domanda或Risposta的LinkList元素不足4个,会抛出IndexOutOfBoundsException,中断后续代码执行(比如服务端调用后的表格渲染)。
修复代码:
修改Link相关的Label和TextColumn,加入空值和长度判断:
问题Grid的Link处理:
// Link1 Label link1 = new Label(); if (currentSelection.getLinkList() != null && currentSelection.getLinkList().size() > 0) { link1.setText(currentSelection.getLinkList().get(0)); } answerGridPanel.setWidget(4, 1, link1); // 同理处理Link2-Link4 Label link2 = new Label(); if (currentSelection.getLinkList() != null && currentSelection.getLinkList().size() > 1) { link2.setText(currentSelection.getLinkList().get(1)); } answerGridPanel.setWidget(5, 1, link2); // ... 以此类推
答案表格的Link列处理:
questionsTable.addColumn(new TextColumn<Risposta>() { @Override public String getValue(Risposta risposta) { if (risposta.getLinkList() != null && risposta.getLinkList().size() > 0) { return risposta.getLinkList().get(0); } return ""; // 或者显示"无链接" } }, "Link"); // 其他Link列同理
3. 服务端RPC调用异常(可能返回空列表或触发onFailure)
你提到数据库有数据但没返回,需要排查服务端的ordinaRisposte方法:
- 检查请求参数:在前端添加日志,确认
currentSelection.getIdQuestion()的数值是否正确(比如是不是0或者无效ID):final int id = currentSelection.getIdQuestion(); Window.alert("查询的问题ID: " + id); // 临时添加,测试后删除 - 查看RPC请求响应:打开Chrome DevTools的「Network」面板,找到
ordinaRisposte的RPC请求,查看Response内容:- 如果返回空数组
[],说明服务端查询到的列表为空,需要检查MapDB的查询逻辑 - 如果返回错误信息,说明服务端抛出了异常,需要查看服务端日志
- 如果返回空数组
- 增强onFailure的错误提示:当前的弹窗只显示"Errore",看不到具体错误,修改代码打印详细错误:
@Override public void onFailure(Throwable caught) { PopupPanel popup = new PopupPanel(true); popup.setWidget(new HTML("<font color='red'>Errore: " + caught.getMessage() + "</font>")); popup.center(); // 同时打印到控制台 com.google.gwt.user.client.Window.alert("详细错误: " + caught.getMessage()); }
4. MapDB服务端查询问题
如果服务端返回空列表,检查MapDB的查询逻辑:
- 确认数据库文件路径正确,没有被误删除或损坏
- 检查查询条件:比如是不是用了错误的键名(比如
"risposte_" + id是不是和存储时的键一致) - MapDB 1.0.9版本需要注意事务处理:如果是写操作后没有提交事务,可能导致数据无法读取,确保服务端查询时的DB实例是正确打开的:
// 示例服务端代码 public List<Risposta> ordinaRisposte(int id) { DB db = DBMaker.newFileDB(new File("path/to/your/db")).closeOnJvmShutdown().make(); try { // 假设存储时用的键是"risposte_" + id List<Risposta> risposte = db.get("risposte_" + id); // 排序逻辑... return risposte; } finally { db.close(); } }
按照以上步骤排查,应该能定位到问题所在。先从前端的代码冲突和索引越界问题入手,这两个是最容易触发的。
内容的提问来源于stack exchange,提问作者GmaxHD
相关产品推荐
相关产品推荐

