我有一个在Tomcat 9上运行的Java应用程序。该项目的一个依赖是mysql-connector-java-5.1.18-bin
(在pom.xml
上声明),因为程序在某些条件下访问MySQL数据库。
在doGet
方法(即请求)上访问数据库时没有问题。
然而,在开发之后,我必须创建一个每30分钟运行一次的作业,并在服务器启动时启动。此方法访问数据库。
调用该方法并将其修复为按照以下方式每30分钟运行一次(如this question所示):
public void contextInitialized(ServletContextEvent arg0) {
// Tasks done on server start
Timer t = new Timer();
MyTask mTask = new MyTask();
// Runs every 30 minutes
t.scheduleAtFixedRate(mTask, 0, 1800000);
}
并在web.xml上声明如下:
<listener>
<listener-class>
timed.MyServletContextListener
</listener-class>
</listener>
然而,在开始和后续循环时,我得到了这个例外:
java.sql.SQLException:找不到合适的驱动程序 JDBC:MySQL的://本地主机:3306 / IOT
但是,在第一次向servlet发出请求后(通过doGet()
),此错误消失,作业设法正常运行。
似乎servlet在发出请求之前无法找到依赖项。有办法解决这个问题吗?或者我是否必须先提出请求?
修改
这里是web.xml
文件:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>IOTServer</display-name>
<context-param>
<param-name>AppID</param-name>
<param-value>123</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
</param-value>
</context-param>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>default.html</welcome-file>
</welcome-file-list>
<listener>
<listener-class>
timed.MyServletContextListener
</listener-class>
</listener>
</web-app>
这是servlet类:
@WebServlet(value="/iotIN", loadOnStartup=1)
public class IoTIN extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// make the necessary operations
}
答案 0 :(得分:0)
contextInitialized 在初始化Web应用程序中的任何过滤器或servlet之前,会通知所有ServletContextListener上下文初始化。 检查数据库连接池的初始化,尝试直接从侦听器类初始化它。 或者,您可以将此调度程序任务调用移动到任何servlet的init()方法,并且不要忘记删除该servlet的延迟加载。
答案 1 :(得分:0)
经过一些更改和新功能之后,我成功地找到了答案。据我所知,驱动程序需要在getGonnection()
函数中明确声明。
基于this answer,这是代码:
public static Connection getConnection() {
String driver = "com.mysql.jdbc.Driver";
String DB_username = "root";
String DB_password = "pass";
String DB_URL = "jdbc:mysql://localhost:3306/DATABASE";
try {
Class.forName(driver);
java.sql.Connection con = DriverManager.getConnection(DB_URL, DB_username, DB_password);
return con;
} catch (ClassNotFoundException | SQLException e) {
System.out.println("Exception " + e);
return null;
}
}
似乎要点在Class.forName()
行。还有一些关于它的信息here。
如果有人想知道,这是以前的getConnection()
功能(不起作用):
public static Connection getConnection() throws SQLException {
Connection conn = null;
Properties connectionProps = new Properties();
connectionProps.put("user", "root");
connectionProps.put("password", "root");
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/DATABASE",
connectionProps);
return conn;
}