서블릿 초기화 매개변수란 서블릿을 생성하고 초기화할 때, 즉 init()을 호출할 때 서블릿 컨테이너가 전달하는 데이터이다. 보통 데이터베이스 연결 정보와 같은 정적인 데이터를 서블릿에 전달할 때 사용한다.
서블릿 초기화 매개변수는 DD파일(web.xml)의 서블릿 배치 정보에 설정할 수 있고, 애노테이션을 사용하여 서블릿 소스 코드에 설정할 수 있다.
서블릿 초기화 매개변수는 그 매개변수가 선언된 서블릿에서만 사용될 수 있으므로 다른 서블릿은 참조할 수 없다. 따라서 JDBC 드라이버와 데이터베이스 연결 정보에 대한 초기화 매개변수를 각 서블릿마다 별도로 설정해 주어야 한다. 이 작업은 매우 번거롭고 낭비적이므로 컨텍스트 초기화 매개변수를 사용하면 된다. 컨텍스트 초기화 매개변수는 같은 웹 어플리케이션에 소속된 서블릿들이 공유하는 매개변수이다.
여기에서는 컨텍스트 초기화 매개변수를 활용해 보겠다.
src/spms/servlet/MemberListServlet.java
while(rs.next()) {
out.println(
rs.getInt("MNO") + "," +
"<a href='update?no=" + rs.getInt("MNO") + "'>" +
rs.getString("MNAME") + "</a>," +
rs.getString("EMAIL") + "," +
rs.getDate("CRE_DATE") + "<br>"
);
}
회원 상세 정보 링크의 URL은 'update'이다.
<!-- 컨텍스트 초기화 파라미터 -->
<context-param>
<param-name>driver</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</context-param>
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost/practicedb</param-value>
</context-param>
<context-param>
<param-name>username</param-name>
<param-value>study</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>1111</param-value>
</context-param>
위처럼 소스 파일 밖에 DB 정보를 두면 나중에 DB정보가 바뀌더라도 web.xml만 편집하면 되므로 유지보수가 쉬워진다.
src/spms/servlet/MemberUpdateServlet.java
@SuppressWarnings("serial")
@WebServlet("/member/update")
public class MemberUpdateServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
ServletContext sc = this.getServletContext();
Class.forName(sc.getInitParameter("driver"));
conn = DriverManager.getConnection(
sc.getInitParameter("url"),
sc.getInitParameter("username"),
sc.getInitParameter("password"));
stmt = conn.createStatement();
rs = stmt.executeQuery(
"SELECT MNO,EMAIL,MNAME,CRE_DATE FROM MEMBERS" +
" WHERE MNO=" + req.getParameter("no"));
rs.next();
resp.setContentType("text/html; charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("<html><head><title>회원정보</title></head>");
out.println("<body><h1>회원정보</h1>");
out.println("<form action='update' method='post'>");
out.println("번호: <input type='text' name='no' value='" +
req.getParameter("no") + "' readonly><br>");
out.println("이름: <input type='text' name='name'" +
" value='" + rs.getString("MNAME") + "'><br>");
out.println("이메일: <input type='text' name='email'" +
" value='" + rs.getString("EMAIL") + "'><br>");
out.println("가입일: " + rs.getDate("CRE_DATE") + "<br>");
out.println("<input type='submit' value='저장'>");
out.println("<input type='button' value='삭제' "
+ "onclick='location.href=\"delete?no=" +
req.getParameter("no") + "\";'>");
out.println("<input type='button' value='취소'" +
" onclick='location.href=\"list\"'>");
out.println("</form>");
out.println("</body></html>");
} catch (Exception e) {
throw new ServletException(e);
} finally {
try {if (rs != null) rs.close();} catch(Exception e) {}
try {if (stmt != null) stmt.close();} catch(Exception e) {}
try {if (conn != null) conn.close();} catch(Exception e) {}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
Connection conn = null;
PreparedStatement stmt = null;
try {
ServletContext sc = this.getServletContext();
Class.forName(sc.getInitParameter("driver"));
conn = DriverManager.getConnection(
sc.getInitParameter("url"),
sc.getInitParameter("username"),
sc.getInitParameter("password"));
stmt = conn.prepareStatement(
"UPDATE MEMBERS SET EMAIL=?,MNAME=?,MOD_DATE=now()"
+ " WHERE MNO=?");
stmt.setString(1, req.getParameter("email"));
stmt.setString(2, req.getParameter("name"));
stmt.setInt(3, Integer.parseInt(req.getParameter("no")));
stmt.executeUpdate();
resp.sendRedirect("list");
} catch (Exception e) {
throw new ServletException(e);
} finally {
try {if (stmt != null) stmt.close();} catch(Exception e) {}
try {if (conn != null) conn.close();} catch(Exception e) {}
}
}
컨텍스트 초기화 매개변수의 값을 얻으려면 ServletContext 객체가 필요하다. HttpServlet으로부터 상속받은 getServletContext()를 호출하여 ServletContext 객체를 준비한다.
ServletContext sc = this.getServletContext();
이 객체를 통해 getInitParameter()를 호출하면 web.xml에 선언된 컨텍스트 초기화 매개변수 값을 얻을 수 있다.
이전 방식
이전 예제에서는 다음과 같이 직접 드라이버 클래스의 인스턴스를 생성하여 JDBC 드라이버를 등록했다.
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
클래스 로딩
Class.forName()을 사용하여 JDBC 드라이버 클래스, 즉 java.sql.Driver를 구현한 클래스를 로딩한다.
Class.forName(/* JDBC 드라이버 클래스의 이름 */)
Class.forName()은 인자값으로 클래스 이름을 넘기면 해당 클래스를 찾아 로딩한다. 클래스 이름은 반드시 패키지 이름을 포함해야 한다. 보통 영어로 'fully qualified name' 또는 'QName' 이라고 표현한다.
컨텍스트 초기화 매개변수의 값 꺼내기
sc.getInitParameter(/* 매개변수 이름 */)
getInitParameter()는 배치 정보가 있는 web.xml로부터 컨텍스트 초기화 매개변수의 값을 꺼내 준다.
getInitParameter -> com.mysql.jdbc.Driver
("driver") -> driver
이렇게 초기화 매개변수를 이용하면 유지 보수가 쉽고 드라이버를 바꾸고 싶을 때 간단히 web.xml만 변경하면 된다.
혹시 어떤 책을 보고 정리하신 걸까요, 아니면 독학으로 여기까지 만드신건가요? 나올만한 내용은 다 나왔습니다만 혹시 연재되지 않은 뒷부분이 더 있는지 몹시 궁금합니다!