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

Java Servlet登录页面无需正确凭据即可登录问题求助

登录验证失效问题排查与修复

我是StackOverflow新手,近期用Java Servlet和数据库开发了带登录、注册功能的项目。昨天代码运行正常:输入错误凭据时,会提示“未找到数据,请点击注册”;但今天跑相同代码,输错凭据居然直接跳过验证登录了,求帮忙解决。

MyShopDAOimpl代码

package login.sg.registration;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class ShopDAOimpl implements ShopDAO {

    static Connection con;
    static PreparedStatement ps;
    
    @Override
    public int insertShopName(Shop s) {
        
        int status=0;
        try {
            con=MyConnectionProvider.getCon();
            ps=con.prepareStatement("insert into shop123  (id,shopName,password,ownerName,address) values(?,?,?,?,?)");
            ps.setString(1, s.getId());
            ps.setString(2, s.getShopname());
            ps.setString(3, s.getPassword());
            ps.setString(4, s.getName());
            ps.setString(5, s.getAddress());
            //System.out.println("new comment" + s.getShopname());
            status=ps.executeUpdate();
            System.out.println("insert ps  " + ps);
            con.close();
            
            
        }catch(Exception e) {
            System.out.println(e);
        }
        return status;
    }

    @Override
    public Shop getShop(String Shopname, String pass) {
        
        Shop s= new Shop();
        try {
            con=MyConnectionProvider.getCon();  
            //System.out.println("after connection");
            ps=con.prepareStatement("select * from  shop123 where shopname=? and password=?");
            ps.setString(1, Shopname);
            ps.setString(2, pass);
            //System.out.println(ps);
            System.out.println(Shopname);
            ResultSet rs=ps.executeQuery();
            while(rs.next()) {
                s.setShopname(rs.getString(1));
                s.setPassword(rs.getString(2));
                s.setName(rs.getString(3));
            }
            }catch(Exception e) {
            System.out.println(e);
        }
    return s;
        
    }

    }

LoginRegister代码

package login.sg.registration;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;



@WebServlet("/LoginRegister")
public class LoginRegister extends HttpServlet {
    private static final long serialVersionUID = 1L;
        


    public LoginRegister() {
        super();
        // TODO Auto-generated constructor stub
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        ShopDAO S= new ShopDAOimpl();
        String submitType=request.getParameter("submit");

        if(submitType.equals("login")){
            String shopName=request.getParameter("name");
               // System.out.println(shopName);
                String password=request.getParameter("password1");

                Shop s=S.getShop(shopName, password);
                System.out.println(s.getShopname()+s.getPassword());
            request.setAttribute("message", s.getName());
            request.getRequestDispatcher("Home.jsp").forward(request, response);
            
        }else if(submitType.equals("register")) {
            //System.out.println("register now function starts");
            Shop s = new Shop();
            s.setShopname(request.getParameter("shopname"));
            //System.out.println("test comment " +request.getParameter("shopname"));
            s.setPassword(request.getParameter("password1"));
            s.setName(request.getParameter("name"));
            s.setAddress(request.getParameter("address"));
            s.setId(request.getParameter("id"));
            request.getParameter ("password1");
            S.insertShopName(s);
            request.setAttribute("successMessage","Registration Sucessfull!!!...login using your credentials");
            request.getRequestDispatcher("login.jsp").forward(request, response);   
            
            
        }else {
            request.setAttribute("message","Data Not Found,click on Register !!!");
            request.getRequestDispatcher("login.jsp").forward(request, response);       
            }

    }

}

问题原因与修复方案

核心问题

  1. DAO层查询逻辑缺失判断:getShop方法无论查询是否命中数据,都会返回一个新建的Shop对象。当输入错误凭据时,查询结果为空,但返回的对象属性都是默认值(比如空字符串),而非null。
  2. Servlet层未做有效性校验:登录分支里直接拿返回的Shop对象跳转首页,完全没判断这个对象是否真的对应数据库里的有效用户。

修复步骤

1. 修改ShopDAOimpl的getShop方法

当查询结果为空时,返回null而非空对象:

@Override
public Shop getShop(String Shopname, String pass) {
    Shop s = null; // 初始化为null
    try {
        con = MyConnectionProvider.getCon();  
        ps = con.prepareStatement("select * from shop123 where shopname=? and password=?");
        ps.setString(1, Shopname);
        ps.setString(2, pass);
        ResultSet rs = ps.executeQuery();
        if(rs.next()) { // 用if而非while,因为用户名密码唯一,只会有一条结果
            s = new Shop(); // 仅当有数据时才创建对象
            s.setShopname(rs.getString("shopName")); // 建议用列名而非索引,避免字段顺序变更出错
            s.setPassword(rs.getString("password"));
            s.setName(rs.getString("ownerName"));
        }
        con.close(); // 确保连接关闭
    } catch(Exception e) {
        e.printStackTrace(); // 打印完整栈轨迹,方便排查错误
    }
    return s;
}

2. 修改LoginRegister的doPost方法登录分支

增加用户有效性判断,无效则跳回登录页并提示错误:

if(submitType.equals("login")){
    String shopName = request.getParameter("name");
    String password = request.getParameter("password1");

    Shop s = S.getShop(shopName, password);
    if(s != null) { // 仅当查询到有效用户时才跳转首页
        request.setAttribute("message", s.getName());
        request.getRequestDispatcher("Home.jsp").forward(request, response);
    } else { // 无匹配用户,返回登录页提示错误
        request.setAttribute("message","Data Not Found,click on Register !!!");
        request.getRequestDispatcher("login.jsp").forward(request, response);
    }
}

额外优化建议

  • 数据库连接管理:用try-with-resources自动关闭Connection、PreparedStatement和ResultSet,避免资源泄漏:
    try (Connection con = MyConnectionProvider.getCon();
         PreparedStatement ps = con.prepareStatement(sql)) {
        // 执行操作
    } catch(Exception e) {
        e.printStackTrace();
    }
    
  • 密码安全:不要明文存储密码,注册时对密码进行哈希(比如用BCrypt),登录时比对哈希值而非明文。
  • 静态变量风险:DAO里的con和ps是静态变量,多线程环境下会导致并发问题,改成方法内局部变量。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:45:36