首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

JSP 連接 MySQL 在另一台電腦報 NullPointerException:連接對象為空排查全流程

     編輯:程式設計綜合問答

異常堆疊分析


java.lang.NullPointerException
    com.zy.dao.DBConBean.query(DBConBean.java:37)  // stat = conn.createStatement();
    org.apache.jsp.Page_005fuser_jsp._jspService(Page_005fuser_jsp.java:161)

**直接原因**:`conn` 為 `null`,調用 `conn.createStatement()` 拋 NPE。
**根本原因**:`getConnection()` 內部捕獲異常後**未拋出/返回 null**,導致調用者拿到 null 連接。

問題代碼缺陷


public static Connection getConnection() {
    try {
        Class.forName("com.mysql.jdbc.Driver");
        conn = DriverManager.getConnection(URL, USER, PASSWORD);
    } catch (ClassNotFoundException e) {
        e.printStackTrace(); // 只打印,不拋出,方法繼續執行返回 null
    } catch (SQLException e) {
        e.printStackTrace(); // 同上
    }
    return conn; // 異常時 conn 仍為 null
}

修正版:拋出異常讓調用者感知失敗


public class DBConBean {
    private static final String URL = "jdbc:mysql://127.0.0.1:3306/bank?useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8";
    private static final String USER = "root";
    private static final String PASSWORD = ""; // 生產環境嚴禁空密碼,必須用配置文件注入

    // 線程不安全!單例連接僅適合單線程測試,生產必須用連接池
    public static Connection getConnection() throws SQLException {
        try {
            // JDBC 4.0+ (Driver 自動註冊) 可省略 Class.forName
            return DriverManager.getConnection(URL, USER, PASSWORD);
        } catch (SQLException e) {
            // 包裝豐富上下文
            throw new SQLException("獲取數據庫連接失敗: " + URL, e);
        }
    }

    // 查詢方法使用 try-with-resources 自動關閉資源 (JDBC 4.1+)
    public static ResultSet query(String sql) throws SQLException {
        Connection conn = getConnection();
        // 調用者必須關閉 ResultSet/Statement/Connection,建議封裝為模板方法
        return conn.createStatement().executeQuery(sql);
    }
}

跨機器部署必檢清單

檢查項命令/操作預期結果
MySQL 服務運行 `systemctl status mysqld` / `services.msc` running
端口監聽 `netstat -an | findstr 3306` / `ss -ntlp | grep 3306` 0.0.0.0:3306 LISTEN
防火牆放行 3306 `firewall-cmd --add-port=3306/tcp --permanent` / Windows 防火牆入站規則 允許
用戶遠程登錄權限 `GRANT ALL ON bank.* TO 'root'@'%' IDENTIFIED BY 'pwd'; FLUSH PRIVILEGES;` 成功
bind-address 配置 `/etc/my.cnf` 或 `my.ini` → `bind-address = 0.0.0.0` 非 127.0.0.1
JDBC 驅動包 WEB-INF/lib/mysql-connector-java-x.x.x.jar 存在且版本匹配 MySQL 版本
連接字符串 IP JSP 中 URL 用**目標機器實際 IP** (非 127.0.0.1) 如 `jdbc:mysql://192.168.1.100:3306/bank`

生產級重構建議

  1. 連接池:HikariCP / Druid / DBCP2,配置 `maximumPoolSize`、`idleTimeout`、`connectionTestQuery`。
  2. DAO 模板:封裝 `executeQuery(sql, rs -> { ... })` 自動關閉資源,避免洩漏。
  3. 配置外部化:`application.properties` / `db.properties` + `@Value` / `Environment` 注入,密碼加密。
  4. 異常統一處理:`@ControllerAdvice` 捕獲 `SQLException` 返回友好錯誤頁/JSON。
  5. SQL 注入防護:務必用 `PreparedStatement` 參數化查詢,拒絕字符串拼接。
  1. 上一篇文章:
  2. 下一篇文章:
VC++ 運行時異常彈窗:指針未初始化/類型錯誤導致 Crash MFC ListView 複製功能失效:SendMessage 句柄傳遞錯誤的定位與修正 Linux 文件跨系統拷貝:權限遺失原因與保留方案 CSS 內部樣式表定義詳解: