You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java爬取数据写入MySQL时出现IndexOutOfBoundsException异常如何解决

异常原因
  1. 该java.lang.IndexOutOfBoundsException为集合索引越界异常,报错显示索引2023超出长度为2023的集合的最大可访问索引(集合索引从0开始,长度为n的集合最大有效索引为n-1)。
  2. 触发场景为代码第101行的循环逻辑:循环以atcId集合的长度为遍历上限,但其他字段对应的集合(如clrNm、rnum等)长度小于atcId,当循环索引超过短集合的最大索引时就会抛出异常。
  3. 导致各字段集合长度不一致的根源是数据解析逻辑错误:代码将接口请求放在了字段遍历的循环内,每提取一个字段就重新调用一次公开接口,若某次接口请求波动返回数据条数变化、或者某条数据缺失对应字段,就会出现各集合长度不匹配的问题,同时重复请求也会大幅降低运行效率、增加接口限流概率。
修复方案

第一步:调整数据解析逻辑,保证各字段集合长度一致

仅请求一次接口,拿到所有item节点后逐个提取对应字段,字段缺失时默认填充空字符串,从根源避免长度不一致问题,替换原字段遍历解析的全部代码:

// 仅调用一次接口获取完整返回数据
Document doc = null;
try {
    doc = Jsoup.connect(url.toString()).get();
} catch (Exception e) {
    e.printStackTrace();
    return; // 接口请求失败直接终止流程,避免后续空指针异常
}
// 提取所有条目节点
Elements itemList = doc.select("item");
// 遍历每个条目一次性提取所有字段
for (Element item : itemList) {
    atcId.add(item.selectFirst("atcId") != null ? item.selectFirst("atcId").text() : "");
    clrNm.add(item.selectFirst("clrNm") != null ? item.selectFirst("clrNm").text() : "");
    depPlace.add(item.selectFirst("depPlace") != null ? item.selectFirst("depPlace").text() : "");
    fdPrdtNm.add(item.selectFirst("fdPrdtNm") != null ? item.selectFirst("fdPrdtNm").text() : "");
    fdSbjt.add(item.selectFirst("fdSbjt") != null ? item.selectFirst("fdSbjt").text() : "");
    fdYmd.add(item.selectFirst("fdYmd") != null ? item.selectFirst("fdYmd").text() : "");
    prdtClNm.add(item.selectFirst("prdtClNm") != null ? item.selectFirst("prdtClNm").text() : "");
    rnum.add(item.selectFirst("rnum") != null ? item.selectFirst("rnum").text() : "");
}

第二步:优化数据库操作逻辑(可选,推荐)

原代码每次循环插入都新建数据库连接,性能极低,调整为批量插入模式,大幅提升入库效率:

Connection con = null;
PreparedStatement pstmt = null;
String driver = "com.mysql.cj.jdbc.Driver";
String dbUrl = "jdbc:mysql://localhost:3306/stuff?useSSL=false&characterEncoding=utf8";
String user = "root";
String pw = "rladydals2@";
String insertSql = "insert into lost_property(atcId, clrNm, depPlace, fdPrdtNm, fdSbjt, fdYmd, prdtClNm, rnum) values(?, ?, ?, ?, ?, ?, ?, ?)";

try {
    Class.forName(driver);
    con = DriverManager.getConnection(dbUrl, user, pw);
    con.setAutoCommit(false); // 开启事务批量提交
    pstmt = con.prepareStatement(insertSql);

    for(int i=0;i<atcId.size();i++) {
        pstmt.setString(1, atcId.get(i));
        pstmt.setString(2, clrNm.get(i));
        pstmt.setString(3, depPlace.get(i));
        pstmt.setString(4, fdPrdtNm.get(i));
        pstmt.setString(5, fdSbjt.get(i));
        pstmt.setString(6, fdYmd.get(i));
        pstmt.setString(7, prdtClNm.get(i));
        pstmt.setString(8, rnum.get(i));
        pstmt.addBatch();
    }
    // 批量执行插入
    int[] executeRes = pstmt.executeBatch();
    con.commit();
    System.out.println("成功插入数据行数:" + executeRes.length);
} catch (ClassNotFoundException | SQLException e) {
    e.printStackTrace();
    // 插入失败回滚事务
    try {
        if (con != null) con.rollback();
    } catch (SQLException rollbackEx) {
        rollbackEx.printStackTrace();
    }
} finally {
    // 统一关闭资源
    if (pstmt != null) {
        try {
            pstmt.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    if (con != null) {
        try {
            con.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

内容的提问来源于stack exchange,提问作者YongMin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 16:30:02