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

使用JSP+JDBC+Servlet开发登录表单遇参数索引越界错误求助

解决JDBC PreparedStatement参数索引越界问题(SQLState: S1009)

你的错误Parameter index out of range (1 > number of parameters, which is 0)是因为SQL语句里把PreparedStatement的占位符?用单引号括起来了。JDBC会将单引号内的内容视为普通字符串,而不是可绑定的参数占位符,导致这条SQL实际没有需要绑定的参数,但你后续调用setString(1, ...)和setString(2, ...)时,就会触发参数索引越界错误。

修正步骤:

直接移除SQL语句中?两侧的单引号即可,修正后的SQL应该是:

SELECT * from myshop.userlogin WHERE username = ? and password = ?

修正后的完整LoginDao代码:

public class LoginDao {

    public boolean validate(LoginBean loginBean) throws ClassNotFoundException {
        boolean status = false;

        Class.forName("com.mysql.cj.jdbc.Driver");

        try (Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myshop?user=root", "root", "12301230");
             PreparedStatement preparedStatement = connection.prepareStatement("SELECT * from myshop.userlogin WHERE username = ? and password = ?")) {
            preparedStatement.setString(1, loginBean.getUsername());
            preparedStatement.setString(2, loginBean.getPassword());

            System.out.println(preparedStatement);
            ResultSet rs = preparedStatement.executeQuery();
            status = rs.next();

        } catch (SQLException e) {
            printSQLException(e);
        }
        return status;
    }

    private void printSQLException(SQLException ex) {
        for (Throwable e: ex) {
            if (e instanceof SQLException) {
                e.printStackTrace(System.err);
                System.err.println("SQLState: " + ((SQLException) e).getSQLState());
                System.err.println("Error Code: " + ((SQLException) e).getErrorCode());
                System.err.println("Message: " + e.getMessage());
                Throwable t = ex.getCause();
                while (t != null) {
                    System.out.println("Cause: " + t);
                    t = t.getCause();
                }
            }
        }
    }
}

额外注意事项:

  • PreparedStatement的占位符?不需要加任何引号,JDBC会根据参数类型自动处理转义和引号包裹,同时还能避免SQL注入风险。
  • 你的数据库连接URL中已经包含了user=root,后续getConnection又传入了用户名参数,虽然不影响功能,但建议统一写法(要么URL里携带,要么通过方法参数传递)。
  • 生产环境绝对不能明文存储用户密码,建议使用BCrypt、Argon2等哈希算法对密码加密后再存入数据库。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 10:01:42