본문 바로가기
교재 실습/자바 웹 개발 워크북

29. 서블릿 초기화 매개변수 (1)

by Jint 2022. 1. 25.

서블릿 초기화 매개변수란 서블릿을 생성하고 초기화할 때, 즉 init()를 호출할 때 서블릿 컨테이너가 전달하는 데이터다. 보통 데이터베이스 연결 정보와 같은 정적인 데이터를 서블릿에 전달할 때 사용한다. 서블릿 초기화 매개변수는 DD파일(web.xml)의 서블릿 배치 정보에 설정할 수 있고, 어노테이션을 사용하여 서블릿 소스 코드에 설정할 수 있다. 가능한 소스 코드에서 분리해 외부 파일에 두는 것을 추천하는데 이는 외부 파일에 두면 변경하기 쉽기 때문이다. 실무에서도 데이터베이스 정보와 같은 시스템 환경과 관련된 정보는 외부 파일에 두어 관리한다.

 

회원 상세 정보를 조회하고 값을 변경하는 서블릿을 작성하고, 서블릿 초기화 매개변수를 이용하여 소스 코드에 있던 데이터베이스 연결 정보를 web.xml 파일로 옮기는 것을 알아본다.

 

MemberListServlet 클래스에 회원 이름 앞뒤로 a태그를 추가한다.

@Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {

	...
	//HTML 태그 출력
	PrintWriter out = response.getWriter();
	out.println("<html><head><title>회원목록</title></head>");
	out.println("<body><h1>회원목록</h1>");
	out.println("<p><a href='add'>신규 회원</a></p>");
	while(rs.next()) {
		out.println(
			rs.getInt("MNO") + "," +
			"<a href='update?no=" + rs.getInt("MNO") + "'>" + //회원 상세정보 출력 서블릿 URL 추가
			rs.getString("MNAME") + "</a>," +
			rs.getString("EMAIL") + "," +
			rs.getDate("CRE_DATE") + "<br>"
		);
	}
    ...
    
}

회원 상세 정보를 출력하는 서블릿의 URL은 '/member/update'로 한다. 'update'로 되어있는 것은 회원 목록(/member/list)과 동일한 경로이기 때문이다. 상세 번호를 조회하려면 회원번호가 필요하므로 이 링크에 'no' 매개변수를 포함시킨다.

 

톰캣 서버를 실행시킨 뒤 웹 브라우저에서 회원 목록을 출력하니 각 회원 이름에 링크가 걸려 있다(그림 1).

그림 1 (회원 이름에 링크가 걸린 회원 목록 화면)

 

web.xml 파일에 MemberUpdateServlet 클래스의 배치 정보를 작성한다.

<?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>web04</display-name>
  
  <!-- 필터 선언 -->
	
	<!-- 필터 URL 매핑 -->
	
	<!-- 서블릿 선언 -->
	<!-- <servlet>
		<servlet-name>MemberList</servlet-name>
  		<servlet-class>spms.servlets.MemberListServlet</servlet-class>
	</servlet> -->
	<servlet>
		<servlet-name>MemberUpdateServlet</servlet-name>
		<servlet-class>spms.servlets.MemberUpdateServlet</servlet-class>
		<init-param>
			<param-name>driver</param-name>
			<param-value>com.mysql.jdbc.Driver</param-value>
		</init-param>
		<init-param>
			<param-name>url</param-name>
			<param-value>jdbc:mysql://localhost/studydb</param-value>
		</init-param>
		<init-param>
			<param-name>username</param-name>
			<param-value>study</param-value>
		</init-param>
		<init-param>
			<param-name>password</param-name>
			<param-value>study</param-value>
		</init-param>
	</servlet>
	
	<!-- 서블릿을 URL과 연결 -->
	<!-- <servlet-mapping>
	  	<servlet-name>MemberList</servlet-name>
	  	<url-pattern>/member/list</url-pattern>
	</servlet-mapping> -->
	<servlet-mapping>
		<servlet-name>MemberUpdateServlet</servlet-name>
		<url-pattern>/member/update</url-pattern>
	</servlet-mapping> 

  <welcome-file-list>
	<welcome-file>index.html</welcome-file>
	<welcome-file>index.htm</welcome-file>
	<welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

<init-param>이 서블릿 초기화 매개변수를 설정하는 태그다. 이 엘리먼트(태그)는 <servlet>의 자식 엘리먼트다.

<init-param>에도 2개의 자식 엘리먼트가 있는데 <param-name>에는 매개변수의 이름을 지정하고 <param-value>에는 매개변수의 값을 지정한다. 매개변수의 값을 여러 개 설정하고 싶으면 <init-param>을 여러개 작성하면 된다. 이런 서블릿 초기화 매개변수들은 오직 그 매개변수를 선언한 서블릿에서만 사용할 수 있으며 다른 서블릿은 사용할 수 없다.

 

이렇게 자바 소스 파일 밖에 DB정보를 두면 나중에 DB정보가 바뀌더라도 web.xml만 편집하면 되기 때문에 유지보수가 편리해진다. 실무에서도 이처럼 변경되기 쉬운 값들은 XML 파일(.xml)이나 프로퍼티 파일(.properties)에 두어 관리한다.

 

spms.servlets 패키지에 MemberUpdateServlet 클래스를 작성한다.

public class MemberUpdateServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;
		try {
			//Class.forName()을 사용하여 JDBC 드라이버 클래스, 즉 java.sql.Driver를 구현한 클래스(com.mysql.jdbc.Driver) 로딩
			//Class.forName(JDBC 드라이버 클래스 이름)
			//HttpServlet 클래스에서 상속받은 getInitParameter()로 서블릿 초기화 매개변수의 값을 꺼낸다.
			//this.getInitParameter(매개변수 이름)
			Class.forName(this.getInitParameter("driver"));
			
			//초기화 매개변수를 이용하여 데이터베이스 연결
			conn = DriverManager.getConnection(
				this.getInitParameter("url"),
				this.getInitParameter("username"),
				this.getInitParameter("password"));
            ...
    	    } catch (Exception e) {
            ...
	}

}

이전 예제에서는 직접 드라이버 클래스의 인스턴스를 생성하여 JDBC 드라이버를 등록했지만 MemberUpdateServlet 클래스에서는 Class.forName()를 사용하여 JDBC 드라이버 클래스, 즉 java.sql.Driver를 구현한 클래스(com.mysql.jdbc.Driver)를 로딩한다. Class.forName()는 인자값으로 클래스 이름을 넘기면 해당 클래스를 찾아 로딩한다. 클래스 이름은 반드시 패키지 이름을 포함해야 하는데 보통 영어로 'fully qualified name' 또는 'QName'이라고 표현한다. 자바 API에서 많이 등장하는 용어다.

 

JDBC 드라이버 클래스의 이름은 서블릿 초기화 매개변수에서 얻어 온다. HttpServlet 클래스에서 상속받은 getInitParameter()를 이용하면 서블릿 초기화 매개변수의 값을 꺼낼 수 있는데, 해당 서블릿의 배치 정보가 있는 web.xml로부터 <init-param>의 매개변수 값을 꺼낸다. getInitParameter()가 반환하는 값은 문자열이다.

그림 2 (서블릿 초기화 매개변수를 꺼내는 getInitParameter())

forName()과 getInitParameter()를 이용하여 JDBC 드라이버를 로딩한다.

 

마찬가지로 데이터베이스에 연결할 때도 초기화 매개변수를 이용한다. JDBC 드라이버나 데이터베이스의 주소, 사용자 이름, 암호가 바뀌더라도 소스코드를 손댈 필요 없이 web.xml만 변경하면 되니 유지보수가 편리하다. 이렇게 서블릿에서 사용하는 설정 값을 초기화 매개변수를 이용하여 관리하면 변경에 대해 유연한 시스템을 개발할 수 있다.

 

참고도서 : https://freelec.co.kr/book/1674/

 

[열혈강의] 자바 웹 개발 워크북

[열혈강의] 자바 웹 개발 워크북

freelec.co.kr

댓글