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 어노테이션을 이용해서 초기화 파라미터를 설정하면,
초기화 설정을 변경할 때 마다 자바 코드를 수정해야 하기 때문에 변경의 유연성이 떨어진다.
'JSP > - 서블릿 (servlet)' 카테고리의 다른 글
JSP - 서블릿 4. URL 패턴 매핑 규칙 (0) | 2020.11.02 |
---|---|
JSP - 서블릿 2. 서블릿 로딩과 초기화(init()) (1) | 2020.11.02 |
JSP - 서블릿 1. 기초 (0) | 2020.11.01 |