前端修复,日志功能加入

This commit is contained in:
Zzzz
2026-04-28 18:26:28 +08:00
parent dc192e8223
commit cc32c222a4
35 changed files with 874 additions and 132 deletions
@@ -8,10 +8,17 @@ import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
public final class JdbcUtil {
private static final Logger LOGGER = Logger.getLogger(JdbcUtil.class.getName());
private static final String CONFIG_FILE = "db.properties";
private static final String DEFAULT_DRIVER = "com.mysql.cj.jdbc.Driver";
private static final String DRIVER_KEY = "db.driver";
private static final String URL_KEY = "db.url";
private static final String USERNAME_KEY = "db.username";
private static final String PASSWORD_KEY = "db.password";
@FunctionalInterface
public interface TransactionCallback<T> {
@@ -23,16 +30,42 @@ public final class JdbcUtil {
public static Connection getConnection() {
Properties properties = loadProperties();
String driver = properties.getProperty("db.driver", DEFAULT_DRIVER);
String url = required(properties, "db.url");
String username = required(properties, "db.username");
String password = required(properties, "db.password");
String driver = properties.getProperty(DRIVER_KEY, DEFAULT_DRIVER);
String url = required(properties, URL_KEY);
String username = required(properties, USERNAME_KEY);
String password = required(properties, PASSWORD_KEY);
LOGGER.info("Database connection configuration resolved"
+ " file=" + CONFIG_FILE
+ " driverKey=" + DRIVER_KEY
+ " driver=" + safeLogValue(driver)
+ " jdbcUrl=" + redactJdbcUrl(url)
+ " usernameKey=" + USERNAME_KEY
+ " usernameConfigured=" + !username.isEmpty()
+ " password=<redacted>");
LOGGER.info("Database connection attempt"
+ " driverKey=" + DRIVER_KEY
+ " driver=" + safeLogValue(driver)
+ " jdbcUrl=" + redactJdbcUrl(url)
+ " usernameKey=" + USERNAME_KEY);
try {
Class.forName(driver);
return DriverManager.getConnection(url, username, password);
} catch (ClassNotFoundException | SQLException ex) {
Connection connection = DriverManager.getConnection(url, username, password);
LOGGER.info("Database connection established jdbcUrl=" + redactJdbcUrl(url)
+ " usernameKey=" + USERNAME_KEY);
return connection;
} catch (ClassNotFoundException ex) {
LOGGER.log(Level.SEVERE, "JDBC driver unavailable driver=" + safeLogValue(driver)
+ " jdbcUrl=" + redactJdbcUrl(url)
+ " usernameKey=" + USERNAME_KEY, ex);
throw new DaoException("Unable to open database connection", ex);
} catch (SQLException ex) {
SQLException safeException = safeSqlException(ex);
LOGGER.log(Level.SEVERE, "Database connection failed driver=" + safeLogValue(driver)
+ " jdbcUrl=" + redactJdbcUrl(url)
+ " usernameKey=" + USERNAME_KEY, safeException);
throw new DaoException("Unable to open database connection", safeException);
}
}
@@ -68,13 +101,20 @@ public final class JdbcUtil {
.getContextClassLoader()
.getResourceAsStream(CONFIG_FILE)) {
if (inputStream == null) {
LOGGER.severe("Database configuration file not found file=" + CONFIG_FILE);
throw new DaoException("Missing database configuration file: " + CONFIG_FILE, null);
}
Properties properties = new Properties();
properties.load(inputStream);
LOGGER.info("Database configuration loaded file=" + CONFIG_FILE
+ " driverConfigured=" + hasText(properties, DRIVER_KEY)
+ " urlConfigured=" + hasText(properties, URL_KEY)
+ " usernameConfigured=" + hasText(properties, USERNAME_KEY)
+ " passwordConfigured=" + hasText(properties, PASSWORD_KEY));
return properties;
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, "Unable to read database configuration file=" + CONFIG_FILE, ex);
throw new DaoException("Unable to read database configuration", ex);
}
}
@@ -82,8 +122,55 @@ public final class JdbcUtil {
private static String required(Properties properties, String key) {
String value = properties.getProperty(key);
if (value == null || value.trim().isEmpty()) {
LOGGER.severe("Missing database configuration value key=" + key);
throw new DaoException("Missing database configuration value: " + key, null);
}
return value.trim();
}
private static String redactJdbcUrl(String value) {
if (value == null) {
return "";
}
return safeLogValue(redactSensitive(value));
}
private static SQLException safeSqlException(SQLException ex) {
SQLException safeException = new SQLException(
safeLogValue(redactSensitive(ex.getMessage())),
ex.getSQLState(),
ex.getErrorCode()
);
safeException.setStackTrace(ex.getStackTrace());
return safeException;
}
private static String redactSensitive(String value) {
if (value == null) {
return "";
}
return value.replaceAll("(?i)(password|pwd|pass|secret|token)(\\s*[=:]\\s*)([^;&\\s]*)", "$1$2<redacted>");
}
private static boolean hasText(Properties properties, String key) {
String value = properties.getProperty(key);
return value != null && !value.trim().isEmpty();
}
private static String safeLogValue(String value) {
if (value == null) {
return "";
}
StringBuilder builder = new StringBuilder();
int limit = Math.min(value.length(), 240);
for (int i = 0; i < limit; i++) {
char current = value.charAt(i);
builder.append(Character.isISOControl(current) ? '?' : current);
}
if (value.length() > limit) {
builder.append("...");
}
return builder.toString();
}
}