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

Java Servlet使用BufferedReader读取txt文件仅能读第一行如何修复

代码存在的问题

  • 提前读取第一行后,仅对第一行的账号密码做了拆分赋值,循环内没有重新拆分新读取的行内容,u和p永远是第一行的账号密码,无法匹配后续行的用户信息
  • while循环的条件中已经执行了br.readLine()读取行,循环体末尾又额外调用了一次br.readLine(),相当于每次循环跳过2行,会漏读内容
  • 循环内的判断逻辑错误:if和else if的判断条件完全一致,无法区分管理员和普通用户;且只要当前读取的行不匹配就直接forward到登录失败页,请求直接终止,根本不会进入下一轮循环读取后续行
  • BufferedReader使用后未关闭,存在资源泄漏问题

修复方案

修改后的完整代码如下:

protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    HttpSession http = request.getSession();

    String path = getServletContext().getRealPath("/WEB-INF/users.txt");
    // 用try-with-resources自动关闭流,避免资源泄漏
    try (BufferedReader br = new BufferedReader(new FileReader(new File(path)))) {

        String userName = request.getParameter("username");
        String passWord = request.getParameter("password");

        String account;
        boolean loginSuccess = false;
        boolean isAdmin = false;

        // 循环读取所有行,每行都拆分比对
        while ((account = br.readLine()) != null) {
            // 跳过空行
            if (account.trim().isEmpty()) {
                continue;
            }
            String[] split = account.split(",");
            String u = split[0].trim();
            String p = split[1].trim();

            if (userName.equals(u) && passWord.equals(p)) {
                loginSuccess = true;
                // 按原文件第一行为管理员账号的规则做判断,可根据实际需求调整规则
                isAdmin = u.equals("admin");
                break;
            }
        }

        // 所有行读取完成后再统一处理跳转逻辑,不要在循环里跳转
        if (loginSuccess) {
            http.setAttribute("username", userName);
            if (isAdmin) {
                getServletContext().getRequestDispatcher("/WEB-INF/admin.jsp").forward(request, response);
            } else {
                getServletContext().getRequestDispatcher("/WEB-INF/inventory.jsp").forward(request, response);
            }
        } else {
            request.setAttribute("message", "The wrong username or password have been entered.");
            getServletContext().getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response);
        }
    }
}

核心修改点说明

  • 用try-with-resources语法管理BufferedReader,自动释放资源无需手动关闭
  • 将账号密码的拆分、比对逻辑移到循环内部,每次读取新行后都更新u和p的值
  • 删除循环内多余的br.readLine()调用,避免漏读
  • 循环内仅做匹配标记,不做跳转,等所有行读取完成后再根据匹配结果统一处理跳转,避免中途终止循环导致后续行无法读取
  • 增加管理员账号判断逻辑,区分admin和普通用户的跳转路径

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 12:15:02