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

解决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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 22:50:39