登录后用户姓氏显示null 排查Servlet/JSP/DAO代码传值问题
问题根源
姓氏显示为null的核心原因很明确:你存进Session的Admin对象,根本没拿到数据库里存的真实姓氏数据。
- 你在Servlet里手动new了一个空Admin实例,只往里面塞了前端请求传的参数。正常登录表单只会让用户填邮箱、密码,根本不会传lastName字段,这一步setLastName拿到的本身就是null。就算你表单里加了lastName输入框,前端传的值也不可信,不是数据库里存的用户真实姓氏。
- 你的AdminDao的loginAdmin方法只返回了是否登录成功的布尔值,根本没把数据库里匹配账号密码查出来的完整用户对象返回。最后存到Session里的永远是你自己new的那个信息残缺的对象,JSP取的时候当然拿不到姓氏。
修复步骤
1. 调整DAO层loginAdmin方法逻辑
不要只返回布尔值,改成返回数据库查询到的完整Admin对象:
- 方法返回值从
boolean改为Admin - 执行SQL查询时,把查到的用户姓氏、其他用户信息都set到Admin实例中
- 账号密码匹配成功就返回填充完整的Admin对象,匹配不到直接返回
null
DAO层参考实现:
public Admin loginAdmin(String email, String password) throws SQLException, ClassNotFoundException { // 保留你原有数据库连接、预编译SQL的逻辑,SQL按邮箱+密码匹配用户 String sql = "select * from admin where email = ? and password = ?"; // 执行查询拿到ResultSet结果集 Admin dbAdmin = null; if(resultSet.next()){ dbAdmin = new Admin(); dbAdmin.setEmail(resultSet.getString("email")); dbAdmin.setLastName(resultSet.getString("last_name")); // 从数据库读取姓氏字段 // 其余需要的用户字段按需从结果集取值set } return dbAdmin; }
2. 修改Servlet登录逻辑
删掉手动new Admin、塞请求参数的代码,直接用DAO返回的对象判断登录状态,把数据库查出来的完整Admin对象存进Session,同时删掉没用的PrintWriter声明(请求转发前手动获取响应输出流很容易引发IllegalStateException异常)。
修改后的doPost代码参考:
@Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { // 只需要从请求拿登录必填的账号、密码参数,不需要拿lastName String email = request.getParameter("email"); String password = request.getParameter("password"); AdminDao adminDao = new AdminDao(); // 调用DAO方法直接拿到数据库匹配到的完整用户对象 Admin currentAdmin = adminDao.loginAdmin(email, password); RequestDispatcher dispatcher = null; if (currentAdmin != null){ // 返回对象不为空即登录成功 HttpSession session = request.getSession(); // 把带完整姓氏信息的用户对象存入Session session.setAttribute("currentSessionAdmin", currentAdmin); dispatcher = request.getRequestDispatcher("Admin_Election.jsp"); }else{ request.setAttribute("status", "failed"); dispatcher = request.getRequestDispatcher("Admin_Login.jsp"); } dispatcher.forward(request, response); } catch (SQLException ex) { Logger.getLogger(adminlogin.class.getName()).log(Level.SEVERE, null, ex); } catch (ClassNotFoundException ex) { Logger.getLogger(adminlogin.class.getName()).log(Level.SEVERE, null, ex); } }
3. 检查JSP取值逻辑
确保Admin_Election.jsp里取姓氏的代码没有写错属性名,EL表达式写法参考:
<div>欢迎您,${currentSessionAdmin.lastName} 管理员</div>
如果用原生Java代码取值,要注意做类型强转:
<% Admin admin = (Admin) session.getAttribute("currentSessionAdmin"); out.print(admin.getLastName()); %>
额外注意事项
- 禁止在请求转发前调用
response.getWriter()或response.getOutputStream(),你原代码里声明的PrintWriter全程没有使用,留着极易导致转发报错 - 登录校验环节只需要向前端索要账号、密码即可,姓氏这类存在数据库的用户信息不要从前端请求传,否则存在数据被恶意篡改的风险
内容的提问来源于stack exchange,提问作者Gidde
相关产品推荐
相关产品推荐

