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` |