Tomcat 시작시 ServletContextListener를 통한 mySQL 접속

■ WAS(Tomcat) 시작할때 DB 접속을 해서 작업을 해야 할 경우에 Listener를 통해서 작업을 할 수 있다. web.xml에 ServletContextListener를 구현한 listener를 등록하면 Tomcat이 시작할 때마다 listener가 실행된다.
 
 
 

■ maven pom.xml, mysql driver dependency 및 tomcat plugin을 추가한다.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.iotinfra</groupId>
<artifactId>pilot.simpletomcat</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<dependencies>
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.35</version>
  </dependency>
</dependencies>

<build>
  <finalName>${project.artifactId}</finalName>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-war-plugin</artifactId>
      <version>2.5</version>
    </plugin>
    <plugin>
      <groupId>org.apache.tomcat.maven</groupId>
      <artifactId>tomcat7-maven-plugin</artifactId>
      <version>2.2</version>
      <configuration>
        <port>9900</port>
        <path>/</path>
        <contextReloadable>true</contextReloadable>
        <systemProperties>
          <JAVA_OPTS>-Xms512m -Xmx512m --XX:MaxPermSize=128m</JAVA_OPTS>
        </systemProperties>
      </configuration>
    </plugin>
  </plugins>
</build>
</project>

 
 
 

■ web.xml( ServletContextListener를 구현한 pilot.simpletomcat.StartupListener를 등록한다.)

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name>simpletomcat</display-name>
   
  <listener>
    <listener-class>pilot.simpletomcat.StartupListener</listener-class>
  </listener>
     
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
   
</web-app>

 
 
 

■ 테스트용 mysql테이블 ‘login_info’ 테이블을 생성한다.

create table `nextdb`.`login_info` (
  `pid` int(10) not null auto_increment primary key,
  `id` varchar(10),
  `count` int(10)
)
engine=InnoDB
default character set = utf8;

 
 
 

■ db 접속 정보를 담은 config-properties.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
  <comment>database configuration</comment>
  <!-- db정보 -->
  <entry key="jdbc.driverClass.master">com.mysql.jdbc.Driver</entry>
  <entry key="jdbc.url.master">jdbc:mysql://127.0.0.1:3306/nextdb</entry>
  <entry key="jdbc.username.master">nextman</entry>
  <entry key="jdbc.password.master">pass</entry>
</properties>

 
 
 

■ config-properties.xml파일을 읽어서 DB접속정보를 담을 DbInfoVO.java

package pilot.simpletomcat;

public class DbInfoVO {
  private String url;
  private String driverClass;
  private String user;
  private String password;
  ...
}

 
 
 

■ config-properties.xml파일을 읽어서 DbInfoVO 객체에 정보를 담는 기능을 하는 DbInfoUtil.java

package pilot.simpletomcat;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class DbInfoUtil {

  private static final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  private DocumentBuilder builder;
  private Document document;

  public DbInfoUtil() {
    try {
      StringBuffer sb = new StringBuffer();
      sb.append(System.getProperty("user.dir"));
      sb.append(File.separator + "config"+File.separator +"config-properties.xml");
      System.out.println( ">>> path : " + sb.toString() );
      
      factory.setValidating(false);
      
      try {
        factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
        builder = factory.newDocumentBuilder();
        document = builder.parse(new File(sb.toString()));
      } 
      catch (ParserConfigurationException pce) {
        pce.printStackTrace();
      } 
      catch (SAXException se) {
        se.printStackTrace();
      } 
      catch (IOException ioe) {
        ioe.printStackTrace();
      }
      
      document.getDocumentElement().normalize();
    }
    catch( Exception e ) {
      e.printStackTrace();
    }
  }
      
  public DbInfoVO getDbInfo() {
    DbInfoVO dbInfo = new DbInfoVO();
      
    Element element = null;
    Node node = null;
    NodeList nodeList = document.getElementsByTagName("entry");
      
    for( int i=0; i<nodeList.getLength(); i++ ) {
      node = nodeList.item(i);
      element = (Element)node;
      
      System.out.println( "" + element.getAttribute("key") +"\t"+ element.getTextContent() );
      
      if( element.getAttribute("key").equals("jdbc.driverClass.master") )
        dbInfo.setDriverClass( element.getTextContent() );
      if( element.getAttribute("key").equals("jdbc.url.master") ) 
        dbInfo.setUrl( element.getTextContent() );
      if( element.getAttribute("key").equals("jdbc.username.master") ) 
        dbInfo.setUser( element.getTextContent() );
      if( element.getAttribute("key").equals("jdbc.password.master") ) 
        dbInfo.setPassword( element.getTextContent() );	
    }
      
    return dbInfo;
  }  
}

 
 
 

■ Tomcat서버가 시작될 때 실행될 StartupListener.java

package pilot.simpletomcat;

import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class StartupListener implements ServletContextListener {

  private Connection conn = null;

  public void contextInitialized(ServletContextEvent sce) {
    DbInfoVO dbInfo = (new DbInfoUtil()).getDbInfo();
    openDB(dbInfo);// connection open
    doWork(); // db 작업
    closeDB();// connection close
  }

  private void doWork() {
    if (conn != null) {
      PreparedStatement pstmt = null;
      try {
        pstmt = (PreparedStatement) conn.prepareStatement("DELETE FROM LOGIN_INFO WHERE ID = 'nextman'");
        pstmt.executeUpdate();
    
        pstmt = (PreparedStatement) conn.prepareStatement("INSERT INTO LOGIN_INFO (ID, COUNT) VALUES (    'nextman',0)");
        pstmt.executeUpdate();
    
        pstmt = (PreparedStatement) conn.prepareStatement("UPDATE LOGIN_INFO SET COUNT = 1 WHERE ID =     'nextman'");
        pstmt.executeUpdate();
      } catch (SQLException e) {
        e.printStackTrace();
      }
    }
  }
    
  private void openDB(DbInfoVO dbInfo) {
    try {
      try {
        java.sql.Driver mySQLDriver = (Driver) Class.forName(dbInfo.getDriverClass()).newInstance();
        DriverManager.registerDriver(mySQLDriver);
      } catch (Exception e) {
        e.printStackTrace();
      }
      conn = DriverManager.getConnection(dbInfo.getUrl(), dbInfo.getUser(), dbInfo.getPassword());
    } 
    catch (SQLException sqle) {
      sqle.printStackTrace();
    } 
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  private void closeDB() {
    try {
      if (conn != null) {
        conn.close();
        conn = null;
      }
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }
  
  public void contextDestroyed(ServletContextEvent sce) {}
}

 
 
 

■ Eclipse에서 본 파일 구성