JSP登录验证页面verifyUser.jsp第45行异常,该如何修复?
解决方案
让我帮你分析一下这个问题,核心是finally块的空指针异常导致的,还有几个潜在问题可以一起优化:
1. 修复核心异常:finally块的NullPointerException
你的代码在finally块直接调用conn.close();,但如果try块中数据库连接创建失败(比如驱动加载错误、数据库未启动、账号密码错误),conn会是null,这时候调用close()就会抛出空指针异常——这就是第45行报错的原因。
修复代码:
finally{ // 先判断连接是否不为null,再关闭 if(conn != null){ try{ conn.close(); }catch(SQLException e){ // 打印异常方便排查问题 e.printStackTrace(); } } }
2. 优化资源释放,避免连接泄漏
除了Connection,PreparedStatement和ResultSet也需要手动关闭,否则会导致数据库连接池资源泄漏。建议把这些对象都声明在try块外,然后在finally块按逆序关闭:
<% String userid = request.getParameter("userID"); String password = request.getParameter("pwd"); Connection conn = null; PreparedStatement pstmt = null; // 新增声明 ResultSet rs = null; // 新增声明 try { // ... 原有业务代码 pstmt = conn.prepareStatement(sql); pstmt.setString(1,userid); pstmt.setString(2,password); rs = pstmt.executeQuery(); // ... 原有登录逻辑 }catch (Exception e){ e.printStackTrace(); request.setAttribute("errorMessage", "登录出错,请稍后重试"); RequestDispatcher rd = request.getRequestDispatcher("/login.jsp"); rd.forward(request, response); return; // 防止跳转后代码继续执行 }finally{ // 按逆序关闭资源:ResultSet -> PreparedStatement -> Connection if(rs != null){ try{rs.close();}catch(SQLException e){e.printStackTrace();} } if(pstmt != null){ try{pstmt.close();}catch(SQLException e){e.printStackTrace();} } if(conn != null){ try{conn.close();}catch(SQLException e){e.printStackTrace();} } } %>
3. 解决字符编码问题
你的页面编码是ISO-8859-1,这会导致中文用户名/密码出现乱码问题,建议改成UTF-8:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
同时,在获取请求参数前设置request的编码:
request.setCharacterEncoding("UTF-8");
4. 优化Session处理逻辑
你当前先调用session.invalidate();再创建新Session,这在首次登录时可能会抛出异常(因为Session还未创建)。可以简化成:
if(rs.next()){ // 获取或创建Session HttpSession session = request.getSession(true); session.setAttribute("LOGIN-STATUS", "YES"); session.setAttribute("name", userid); response.sendRedirect("index.jsp"); return; // 跳转后终止代码执行 }
最终修改后的完整代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <%@page import="java.sql.*, javax.servlet.http.HttpSession"%> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <title> Verify User </title> </head> <body> <% request.setCharacterEncoding("UTF-8"); String userid = request.getParameter("userID"); String password = request.getParameter("pwd"); Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try { //Step1: JDBC Driver Class.forName("com.mysql.jdbc.Driver"); //Step2: Define Connection URL String connURL = "jdbc:mysql://localhost/assignment?user=root&password=root&useUnicode=true&characterEncoding=UTF-8"; //Step3: Establish connection to URL conn = DriverManager.getConnection(connURL); String sql = "select * from login where UserId=? and Password=?"; pstmt = conn.prepareStatement(sql); pstmt.setString(1,userid); pstmt.setString(2,password); rs = pstmt.executeQuery(); if(rs.next()){ HttpSession session = request.getSession(true); session.setAttribute("LOGIN-STATUS", "YES"); session.setAttribute("name",userid); response.sendRedirect("index.jsp"); return; } else{ request.setAttribute("errorMessage", "Invalid user or password"); RequestDispatcher rd = request.getRequestDispatcher("/login.jsp"); rd.forward(request, response); return; } }catch (Exception e){ e.printStackTrace(); request.setAttribute("errorMessage", "登录出错,请稍后重试"); RequestDispatcher rd = request.getRequestDispatcher("/login.jsp"); rd.forward(request, response); }finally{ if(rs != null){ try{rs.close();}catch(SQLException e){e.printStackTrace();} } if(pstmt != null){ try{pstmt.close();}catch(SQLException e){e.printStackTrace();} } if(conn != null){ try{conn.close();}catch(SQLException e){e.printStackTrace();} } } %> </body> </html>
内容的提问来源于stack exchange,提问作者Rachel k
相关产品推荐
相关产品推荐

