Java/JavaFX - 在尝试数据库连接时检查互联网连接是否存在
Java/JavaFX - check if internet connection exists upon trying db connection
假设我在 JavaFX 中创建了一个简单的登录 window,它通过连接到 postgresql 数据库来检查用户名和密码是否相互匹配,并在成功后让用户登录。
现在,只要存在 Internet 连接,它就可以正常工作。
但是,如果没有 Internet 连接,JVM 会反复发出 PSQLExceptions 并且应用程序会冻结一分钟左右。我以为我在连接中捕捉到这些 class。由SocketTimeoutException引起。
有没有人对我如何处理此问题有任何提示,以便在 GUI 中显示错误消息而不是冻结和异常?
我的连接 class 看起来像这样:
public class DBConnection {
/* DB credentials, modify as needed */
private static final String HOST = "<HOST>";
private static final String DATABASE = "<DATABASE>";
private static final String USERNAME = "<USERNAME>";
private static final String PASSWORD = "<PASSWORD>";
private static final String PORT = "5432";
/* !!DO NOT EDIT BELOW!! */
private static final String JDBC_DRIVER = "org.postgresql.Driver";
private static final String URL = "jdbc:postgresql://" + HOST + ":" + PORT + "/" + DATABASE;
private static final ComboPooledDataSource POOL = new ComboPooledDataSource();
private static Connection conn = null;
public static void Connect() throws PropertyVetoException, SQLException{
try {
POOL.setDriverClass(JDBC_DRIVER);
}catch (PropertyVetoException e){
System.out.println("Could not locate JDBC driver");
e.printStackTrace();
throw e;
}
//Connection parameters
POOL.setJdbcUrl(URL);
POOL.setUser(USERNAME);
POOL.setPassword(PASSWORD);
//Pool properties
POOL.setMinPoolSize(3);
POOL.setAcquireIncrement(5);
POOL.setMaxPoolSize(100);
POOL.setMaxStatements(180);
try {
conn = POOL.getConnection();
} catch (SQLException e) {
System.out.println("Could not establish connection to database");
e.printStackTrace();
throw e;
}
}
public static ResultSet ExecuteQuery(String query) throws PropertyVetoException, SQLException {
PreparedStatement st = null;
ResultSet rs = null;
CachedRowSet crs = null;
try {
Connect();
System.out.println("Select statement: " + query + "\n");
st = conn.prepareStatement(query);
rs = st.executeQuery();
crs = new CachedRowSetImpl();
crs.populate(rs);
}catch (Exception e){
System.out.println("Problem occurred at executeQuery operation: " + e);
throw e;
}finally {
DbUtils.closeQuietly(conn, st, rs);
}
return crs;
}
public static void ExecuteUpdate(String query) throws PropertyVetoException, SQLException {
PreparedStatement st = null;
try {
Connect();
st = conn.prepareStatement(query);
st.executeUpdate();
}catch (Exception e){
System.out.println("Problem occurred at executeUpdate operation: " + e);
throw e;
}finally {
DbUtils.closeQuietly(st);
DbUtils.closeQuietly(conn);
}
}
}
像往常一样,添加另一个抽象层来解决您的问题。
意思是:你可以有一个class负责理解"are we connected"。它可以通过定期 ping 数据库服务器来获取该信息(有关如何执行该操作的想法,请参阅 here)。所以,在你要求建立连接之前,你要征求 "AreWeConnectedService" 的意见。
该服务基本上是这样工作的:
- 它有一个内部字段 "connected"
- 它有一个内部线程,该线程会定期 ping 另一端
- 如果 ping 失败你去
connected = false
(你可能还记得时间戳)
- 如果 ping 在某个时候再次工作,您将再次切换该字段
然后该服务有一个查询该标志的方法。
当然,您仍然可能在服务告诉您后立即断开连接 "everything fine"。因此,您必须进一步退后一步并修复问题的 "other part":您必须使用 另一个 线程,然后使用 SwingUX 线程来执行该 getConnection()
调用。理想情况下,您甚至可以使用两个线程:一个进行实际调用;另一个进行实际调用。另一个是强制超时。
除此之外:确保您也阅读并理解了 Oracle 必须告诉您的有关 Concurrency in JavaFx! And another link - you might want to look into the Circuit breaker 模式的内容。
假设我在 JavaFX 中创建了一个简单的登录 window,它通过连接到 postgresql 数据库来检查用户名和密码是否相互匹配,并在成功后让用户登录。
现在,只要存在 Internet 连接,它就可以正常工作。
但是,如果没有 Internet 连接,JVM 会反复发出 PSQLExceptions 并且应用程序会冻结一分钟左右。我以为我在连接中捕捉到这些 class。由SocketTimeoutException引起。
有没有人对我如何处理此问题有任何提示,以便在 GUI 中显示错误消息而不是冻结和异常?
我的连接 class 看起来像这样:
public class DBConnection {
/* DB credentials, modify as needed */
private static final String HOST = "<HOST>";
private static final String DATABASE = "<DATABASE>";
private static final String USERNAME = "<USERNAME>";
private static final String PASSWORD = "<PASSWORD>";
private static final String PORT = "5432";
/* !!DO NOT EDIT BELOW!! */
private static final String JDBC_DRIVER = "org.postgresql.Driver";
private static final String URL = "jdbc:postgresql://" + HOST + ":" + PORT + "/" + DATABASE;
private static final ComboPooledDataSource POOL = new ComboPooledDataSource();
private static Connection conn = null;
public static void Connect() throws PropertyVetoException, SQLException{
try {
POOL.setDriverClass(JDBC_DRIVER);
}catch (PropertyVetoException e){
System.out.println("Could not locate JDBC driver");
e.printStackTrace();
throw e;
}
//Connection parameters
POOL.setJdbcUrl(URL);
POOL.setUser(USERNAME);
POOL.setPassword(PASSWORD);
//Pool properties
POOL.setMinPoolSize(3);
POOL.setAcquireIncrement(5);
POOL.setMaxPoolSize(100);
POOL.setMaxStatements(180);
try {
conn = POOL.getConnection();
} catch (SQLException e) {
System.out.println("Could not establish connection to database");
e.printStackTrace();
throw e;
}
}
public static ResultSet ExecuteQuery(String query) throws PropertyVetoException, SQLException {
PreparedStatement st = null;
ResultSet rs = null;
CachedRowSet crs = null;
try {
Connect();
System.out.println("Select statement: " + query + "\n");
st = conn.prepareStatement(query);
rs = st.executeQuery();
crs = new CachedRowSetImpl();
crs.populate(rs);
}catch (Exception e){
System.out.println("Problem occurred at executeQuery operation: " + e);
throw e;
}finally {
DbUtils.closeQuietly(conn, st, rs);
}
return crs;
}
public static void ExecuteUpdate(String query) throws PropertyVetoException, SQLException {
PreparedStatement st = null;
try {
Connect();
st = conn.prepareStatement(query);
st.executeUpdate();
}catch (Exception e){
System.out.println("Problem occurred at executeUpdate operation: " + e);
throw e;
}finally {
DbUtils.closeQuietly(st);
DbUtils.closeQuietly(conn);
}
}
}
像往常一样,添加另一个抽象层来解决您的问题。
意思是:你可以有一个class负责理解"are we connected"。它可以通过定期 ping 数据库服务器来获取该信息(有关如何执行该操作的想法,请参阅 here)。所以,在你要求建立连接之前,你要征求 "AreWeConnectedService" 的意见。
该服务基本上是这样工作的:
- 它有一个内部字段 "connected"
- 它有一个内部线程,该线程会定期 ping 另一端
- 如果 ping 失败你去
connected = false
(你可能还记得时间戳) - 如果 ping 在某个时候再次工作,您将再次切换该字段
然后该服务有一个查询该标志的方法。
当然,您仍然可能在服务告诉您后立即断开连接 "everything fine"。因此,您必须进一步退后一步并修复问题的 "other part":您必须使用 另一个 线程,然后使用 SwingUX 线程来执行该 getConnection()
调用。理想情况下,您甚至可以使用两个线程:一个进行实际调用;另一个进行实际调用。另一个是强制超时。
除此之外:确保您也阅读并理解了 Oracle 必须告诉您的有关 Concurrency in JavaFx! And another link - you might want to look into the Circuit breaker 模式的内容。