解决java.lang.NumberFormatException异常:通过ID展示游戏数据求助
解决
java.lang.NumberFormatException: Cannot parse null string异常问题 我遇到了java.lang.NumberFormatException: Cannot parse null string异常,原本习惯把SQL方法放在单独类中调用,这次尝试用单独方法从数据库获取指定ID的游戏数据来避免遍历全部数据,但运行时出现了这个异常,求解决建议。
相关Servlet代码
package cs3220.servlet; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cs3220.model.Games; @WebServlet("/DisplayGame") public class DisplayGame extends HttpServlet { private static final long serialVersionUID = 1L; public DisplayGame() { super(); // TODO Auto-generated constructor stub } public Games getEntry(int id) { Games entry = new Games(); Connection c = null; try { String url = "jdbc:mysql://cs3.calstatela.edu/cs3220stu16"; String username = "foo"; String password = "bar"; c = DriverManager.getConnection(url, username, password); String sql = "select * from games_list where id = ?"; PreparedStatement pstmt = c.prepareStatement(sql); pstmt.setInt(1, id); ResultSet rs = pstmt.executeQuery(); if (rs.next()) { entry.setId(rs.getInt("id")); entry.setRating(rs.getInt("rating")); entry.setTitle(rs.getString("title")); entry.setComment(rs.getString("comment")); } pstmt.close(); } catch (SQLException e) { e.printStackTrace(); } return entry; } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int id = Integer.parseInt(request.getParameter("id")); DisplayGame ds = new DisplayGame(); request.setAttribute("entry", ds.getEntry(id)); request.getRequestDispatcher("/WEB-INF/DisplayGame.jsp").forward(request, response); } }
问题分析与解决步骤
1. 异常根源
异常出现在doGet方法的Integer.parseInt(request.getParameter("id"))这一行:
- 当请求中没有携带
id参数时,request.getParameter("id")会返回null - 直接对
null调用Integer.parseInt()就会抛出NumberFormatException
2. 核心修复:参数校验
在解析参数前先做校验,处理缺失或无效的情况:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String idStr = request.getParameter("id"); // 检查参数是否存在 if (idStr == null || idStr.trim().isEmpty()) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, "缺少必要的id参数"); return; } int id; try { // 解析参数,处理非数字情况 id = Integer.parseInt(idStr); } catch (NumberFormatException e) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, "id必须是有效的整数"); return; } DisplayGame ds = new DisplayGame(); Games entry = ds.getEntry(id); // 处理数据库未查到数据的情况 if (entry == null) { response.sendError(HttpServletResponse.SC_NOT_FOUND, "未找到指定ID的游戏"); return; } request.setAttribute("entry", entry); request.getRequestDispatcher("/WEB-INF/DisplayGame.jsp").forward(request, response); }
3. 优化数据库查询方法
当前getEntry方法不管是否查到数据都返回空Games对象,建议改为查到数据才创建对象,否则返回null,同时必须关闭数据库连接避免资源泄漏:
public Games getEntry(int id) { Games entry = null; Connection c = null; try { String url = "jdbc:mysql://cs3.calstatela.edu/cs3220stu16"; String username = "foo"; String password = "bar"; c = DriverManager.getConnection(url, username, password); String sql = "select * from games_list where id = ?"; PreparedStatement pstmt = c.prepareStatement(sql); pstmt.setInt(1, id); ResultSet rs = pstmt.executeQuery(); // 查到数据才初始化对象 if (rs.next()) { entry = new Games(); entry.setId(rs.getInt("id")); entry.setRating(rs.getInt("rating")); entry.setTitle(rs.getString("title")); entry.setComment(rs.getString("comment")); } rs.close(); pstmt.close(); } catch (SQLException e) { e.printStackTrace(); } finally { // 确保数据库连接被关闭 if (c != null) { try { c.close(); } catch (SQLException e) { e.printStackTrace(); } } } return entry; }
4. 额外优化建议
- 不要在Servlet中直接创建数据库连接,改用数据库连接池(如HikariCP),提升性能和稳定性
- 将数据库操作封装到独立的DAO类中,遵循单一职责原则,让Servlet只处理请求转发逻辑
内容的提问来源于stack exchange,提问作者Kobe Martinez
相关产品推荐
相关产品推荐

