Java Servlet替换HTML占位符报IndexOutOfBoundsException排查
Java EE Servlet访问deleteServlet抛出IndexOutOfBoundsException排查
问题背景
- 项目为学校课程设计的日志管理模块,核心业务规则:
- 用户提交表单后生成Log实体持久化到MySQL数据库
- 日志列表按
createTimestamp字段排序展示,每条日志条目配套缩略图、删除操作按钮
- 数据层通过
ApplicationDao实现数据库交互,查询结果封装为List<Log>集合,用于替换ListLogs.html模板中{0}/{1}格式的预留占位符 - 开发过程参考Java EE Servlet/JSP相关教程实现,已修正类实例化大小写错误:将错误写法
Log log= new textLog调整为正确的Log log = new TextLog() - 当前异常触发场景:访问
deleteServlet路径时直接抛出异常,栈轨迹定位到deleteServlet类getHTMLString方法第65行的ArrayList.get()调用位置 - 随问题附完整项目代码,包含Log实体类、LogsServlet、deleteServlet、ApplicationDao、DBConnection数据库连接工具类、ListLogs.html模板文件,代码中存在部分调试阶段遗留的重复逻辑,诉求为明确异常排查方向与修复方案。
根因定位方向
这个异常的触发逻辑非常明确:代码对一个长度为0的空ArrayList调用了get(0)方法,结合业务场景按以下优先级排查即可,90%的概率是前两个问题:
- 最高优先级查占位符替换逻辑与传入参数的匹配度:你当前实现的手动占位符替换逻辑,是严格按照下标从传入的
List<Log>中取元素填充模板。如果删除操作执行完成后,没有重新调用DAO查询最新的日志列表,直接将初始化的空列表传入替换方法,当模板解析到第一个{0}占位符需要取第一条日志内容时,必然触发越界错误。 - 次高优先级查deleteServlet的执行链路:检查删除逻辑执行完成后的流程,是否存在以下问题:
- 遗漏调用DAO层查询全量日志的步骤,直接将空列表传入模板替换方法
- 查询SQL存在逻辑错误,比如排序字段写错、携带了错误的过滤条件、数据库连接异常,导致DAO层返回空结果集,代码未做判空直接向下传递
- 删除SQL逻辑错误,漏写
WHERE条件导致全表日志被误删,后续查询自然返回空集合
- 最后排查调试遗留代码:你提到代码中存在调试阶段临时编写的重复逻辑,重点检查是否存在重复定义
List<Log>变量、在某个分支中重新new空列表覆盖了已查询到的有效结果的情况。
修复方案
按排查顺序对应修复即可:
- 首先给
getHTMLString方法增加边界校验,从代码层面避免空集合越界:// 占位符替换前增加判空逻辑 if (logList == null || logList.isEmpty()) { // 直接将列表区域替换为无数据提示,跳过循环取元素的逻辑 return htmlTemplate.replace("<!-- 日志列表容器 -->", "<p>暂无日志记录</p>"); } - 补全deleteServlet的完整执行流程:删除逻辑执行完成后,必须显式调用ApplicationDao中按
createTimestamp排序查询日志的方法,拿到最新的全量日志集合后,再传入模板替换方法,禁止直接使用方法初始化时的空列表。 - 全量清理调试阶段遗留的重复代码,尤其是重复赋值、重复定义集合变量的逻辑块,避免空集合覆盖有效查询结果。
- 在DAO层查询方法中增加调试日志,执行删除流程时打印查询到的日志集合长度,可快速定位是SQL执行异常还是传参链路断裂的问题。
- 校验删除SQL的语法:确认删除语句携带了正确的日志ID作为WHERE条件,避免无差别删除全表数据导致查询结果为空。
优化建议:在Servlet中手动拼接字符串替换HTML占位符的写法维护成本极高,后续调整模板字段时很容易出现参数不匹配的问题,如果课程设计允许,建议直接使用JSP+JSTL标签实现页面循环渲染,不需要手动编写占位符替换逻辑,可大幅减少此类低级错误。
内容的提问来源于stack exchange,提问作者Caitlyn Gibbons
相关产品推荐
相关产品推荐

