contextInitialized()函数对Tomcat 9的依赖性在发出请求之前不加载

时间:2017-10-06 18:00:52

标签: java mysql maven tomcat dependencies

我有一个在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
    }

2 个答案:

答案 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;
}