본문 바로가기

JSP/- 서블릿 (servlet)

JSP - 서블릿 3. 초기화 파라미터

 

 

DBCPInit.java 코드의 일부분

 

public class DBCPInit extends HttpServlet {

    @Override
    public void init() throws ServletException {
        loadJDBCDriver();
        initConnectionPool();
    }
    
    private void loadJDBCDriver() {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException("fail to load JDBC Driver", ex);
        }
    }
    
    private void initConnectionPool() {
        try {
            String jdbcUrl = "jdbc:mysql://localhost:3306/chap14?" + 
                             "useUnicode=true&characterEncoding=utf8";
            String username = "root";
            String pw = "db비밀번호";
            
            ... 코드 생략
    }
}

 

위의 DBCPInit 클래스의 단점!!

 

- JDBC 드라이버 클래스 이름 ("com.mysql.jdbc.Driver");

- JDBC URL (jdbcUrl)

- DB 사용자 정보 (username, pw)

 

코드들이 들어가 있기 때문에 DB를 MySQL 에서 오라클 DB 등으로 변경할 때 직접 코드를 수정해야 한다.

 

초기화 파라미터를 사용하면, 서블릿 코드를 직접 변경하지 않고 사용할 값을 변경할 수 있다.

 

web.xml 의 <init-param> 태크를 사용해서 서블릿을 초기화할 때 필요한 값을 전달하는 방법을

제공하고 있다.

 

<init-param> 태크는 서블릿 초기화 파라미터를 지정할 때 사용되며 자식 태그는 아래와 같다.

 

- <param-name> 태그 : 초기화 파라미터의 이름을 지정한다.

- <param-value> 태그 : 초기화 파라미터의 값을 지정한다.

 

<servlet>
    <servlet-name>DBCPInit2</servlet-name>
    <servlet-class>jdbc.DBCPInit2</servlet-class>
    <init-param>
        <param-name>jdbcdriver</param-name>
        <param-value>com.mysql.jdbc.Driver</param-value>
    </init-param>
    
    <init-param>
        <param-name>poolName</param-name>
        <param-value>chap14</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

 

위 코드는 jdbcDriver 이름의 초기화 파라미터 값으로 com.mysql.jdbc.Driver 를 지정,

poolName 초기화 파라미터 값으로 chap14 지정 한다.

 

서블릿 클래스에서 초기화 파라미터에 접근하려면 getInitParameter() 메소드를 사용한다.

 

초기화 파라미터를 사용해서 커넥션 풀과 관련된 설정 정보를 전달받도록 구현한다.

 

 

chap17/src/jdbc/DBCPInit2.java : 초기화 파라미터 사용

 

package jdbc;

import java.sql.DriverManager;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.apache.commons.dbcp2.ConnectionFactory;
import org.apache.commons.dbcp2.DriverManagerConnetionFactory;
import org.apache.commons.dbcp2.PoolableConnection;
import org.apache.commons.dbcp2.PoolableConnectionFactory;
import org.apache.commons.dbcp2.PoolingDriver;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;

public class DBCPInit2 extends HttpServlet {

    @Override
    public void init() throws ServletException {
        loadJDBCDriver();
        initConnectionPool();
    }
    
    private void loadJDBCDriver() {
        String driverClass = getInitParameter("jdbcdriver");  // jdbcdriver 초기화 파라미터
        try {
            Class.forName(driverClass);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException("fail to load JDBC Driver", ex);
        }
    }
    
    private void initConnectionPool() {
        try {
            String jdbcUrl = getInitParameter("jdbcUrl");  // jdbcUrl 초기화 파라미터
            String username = getInitParameter("dbUser");  // dbUser 초기화 파라미터
            String pw = getInitParameter("dbPass");  // dbPass 초기화 파라미터
            
            ConnectionFactory connFactory =
                new DriverManagerConnectionFactory(jdbcUrl, username, pw);
            
            PoolableConnectionFactory poolableConnFactory =
                new PoolableConnectionFactory(connFactory, null);
            poolableConnFactory.setValidationQuery("select 1");
            
            GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
            
            poolConfig.setTimeBetweenEvictionRunsMillis(1000L, 60L, 5L);
            poolConfig.setTestWhileIdle(true);
            poolConfig.setMinIdle(4);
            poolConfig.setMaxTotal(50);
            
            GenericObjectPool<PoolableConnection> connectionPool =
                new GenericObjectPool<>(poolableConnFactory, poolConfig);
            
            poolableConnFactory.setPool(connectionPool);
            
            Class.forName("org.apache.commons.dbcp2.PoolingDriver");
            PoolingDriver driver = 
                (PoolingDriver)DeriverManager.getDriver("jdbc:apache:commons:dbcp:");
            
            String poolName = getInitParameter("poolName");  //poolName 초기화 파라미터
            
            driver.registerPool(poolName, connectionPool);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}            

 

chap17/WEB-INF/web.xml : DBCPInit2 를 위한 설정

 

<servlet>
    <servlet-name>DBCPInit2</servlet>
    <servlet-class>jdbc.DBCPInit2</servlet-class>
    <init-param>
        <param-name>jdbcdriver</param-name>
        <param-value>com.mysql.jdbc.Driver</param-value>
    </init-param>
    <init-param>
        <param-name>jdbcUrl</param-name>
        <param-value>
            jdbc:mysql://localhost:3306/chap14?characterEncoding=utf8
        </param-value>
    </init-param>
    <init-param>
        <param-name>dbUser</param-name>
        <param-value>root</param-value>
    </init-param>
    <init-param>
        <param-name>dbPass</param-name>
        <param-value>rootpw</param-value>
    </init-param>
    <init-param>
        <param-name>poolName</param-name>
        <param-value>chap14</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

 

JDBC URL 이나 다른 설정을 바꾸려면, 서블릿 코드를 변경할 필요 없이

web.xml 파일의 초기화 파라미터 값을 변경하면 된다.

 

getInitParameter() 메소드는 지정한 초기화 파라미터가 존재하면 해당 값을 리턴하고,

존재하지 않으면 null 을 리턴한다.

 

따라서 null 인 경우 기본값을 사용하고 싶거나, 다른 예외 처리를 하고 싶다면,

초기화 파라미터 값이 null 인지 여부를 확인한 후 알맞게 처리한다.

 

// 초기화 파라미터가 없으면 null 을 리턴한다.

String poolName = getInitParameter("poolName");

if (poolName == null) poolName = "pool";  // null 이라면 기본값 pool 사용

 

* 웹 어플리케이션에서 전반적으로 필요한 초기화 작업을 수행하는 다른 방법으로

  ServletContextListener 를 사용하는 방법도 있다.

 


 

@WebServlet 어노테이션으로 매핑한 경우, 초기화 파라미터를 전달하려면,

 

initParams 속성의 값으로 @WebInitParam 어노테이션 목록을 전달한다.

 

@WebServlet(urlPatterns = {"/hello", "/hello1"},
    initParams = {
        @WebInitParam(name="greeting", value="Hello"),
        @WebInitParam(name="title", value="제목")
    }
}

 

 

* 초기화 파라미터를 사용하는 이유!

 

- 클래스의 수정 없이 초기화 과정에서 필요한 값을 수정할 수 있다.

- 단, WebInitParam 어노테이션을 이용해서 초기화 파라미터를 설정하면,

  초기화 설정을 변경할 때 마다 자바 코드를 수정해야 하기 때문에 변경의 유연성이 떨어진다.