서블릿의 초기화

서블릿은 클라이언트로부터 최초 요청시 단 한번 초기화되며 생성됩니다.
WAS 내부의 서블릿 컨테이너에서 서블릿 객체 생성 후 초기화시에 init()메서드를 호출하는데 이 과정을 서블릿 로딩이라 합니다.
이후 해당 서블릿 객체는 서블릿 컨테이너에서 대기하다가 동일한 요청이 있을시 service()메서드를 통해 요청을 처리합니다.

최초 요청시


이후 요청시

 

 


초기화 메서드 init()
init() 메서드의 경우 HttpServlet의 최상위 클래스인 Servlet 인터페이스에 정의되어 있습니다.
1
public void init(ServletConfig config) throws ServletException;
cs

Servlet의 구현체이며 HttpServlet의 부모 클래스인 GenericServlet에서는 init() 메서드를 다음과 같이 두가지로 구현하고 있습니다.
때문에 우리가 HttpServlet을 상속받아 직접 서블릿 클래스를 만들때 init() 메서드를 오버라이딩 하지 않는다면 기본적으로 GenericServlet의 init()메서드가 호출됩니다.
1
2
3
4
5
6
7
8
    @Override
    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }
 
    public void init() throws ServletException {
    }
cs


서블릿 상속도와 init() 메서드 오버라이딩
서블릿의 기능이나 역할에 따라 서블릿 객체가 생성되는 시점에 필요한 행동들이 있으며, 그에 대한 내용을 원하는 init() 메서드를 오버라이딩하여 구현 합니다.



 

 



init()메서드와 ServletConfig 객체를 이용한 서블릿 초기화 방법
위에서는 언급하지 안았지만 클라이언트로부터 최초 요청시 서블릿 객체 생성 후 init()메서드를 호출할때 ServletConfig를 자동으로 생성하여 넘겨줍니다.
ServletConfig는 서블릿당 하나가 생성되며 web.xml에서 우리가 필요에 따라 입력한 파라미터 값들을 담고 있습니다.

web.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="생략">
    
    <display-name>Servlet Study</display-name>
    <servlet>
        <servlet-name>myServlet</servlet-name>
        <servlet-class>servletStudy.MyServlet</servlet-class>
        <init-param>
            <param-name>dbName</param-name>
            <param-value>mydb</param-value>
        </init-param>
        <init-param>
            <param-name>dbPasswd</param-name>
            <param-value>myPasswd</param-value>
        </init-param>
    </servlet>
    
    
</web-app>
cs

web.xml에서 Servlet 맵핑 설정시에 <init-param> 태그를 통해 서블릿 초기화시 넘겨받을 값들을 설정할 수 있고 값들은 <param-name>과 <param-value>를 통해 지정해줍니다.
그리고 실제 서블릿에서는 다음과 같이 설정한 파라미터값을 가져올 수 있습니다.

getInitParameter(String paramName) - 매개변수로 web.xml에서 지정했던 param-name을 넘겨주면 그에 해당하는 값을 가져옵니다.

MyServlet.java
1
2
3
4
5
6
7
8
9
public class MyServlet extends HttpServlet{
    
    @Override
    public void init(ServletConfig config) throws ServletException {
        String dbnm = config.getInitParameter("dbName"); //mydb
        String dbpwd = config.getInitParameter("dbPasswd"); //myPasswd
    }
    
}
cs

 

ServletConfig를 이용했을때의 이점
ServletConfig를 통해 서블릿을 초기화하게 되면 유지보수성이 높아지는 이점이 생깁니다.
예를 들어 데이터베이스 설정값이라든지, 인코딩 캐릭터셋을 지정할때 web.xml과 ServletConfig를 이용하게 되면 나중에 수정이 되어도 적용이 간편해지기 때문입니다.
만약 해당 값들이 서블릿 클래스 안에 소스상으로 하드코딩 되었을 경우에는 값을 변경하기위해 실제로 운영되고 있는 서버에 소스를 수정하고 컴파일 한 후에 다시 올리는 일을 반복해야 합니다.
그러나 web.xml을 이용하게 되면 해당 xml에서만 값을 고쳐주면 설정을 변경할 수 있게 됩니다.

 

 

@WebServlet 를 이용하여 값 넘기는 법
다음과 같이 애노테이션을 이용하여 값을 넘겨줄수도 있습니다.
그러나 이처럼 소스상에 값 설정이 나타나게 되면 web.xml을 이용했을때와 같은 유지보수성의 이점이 사라지므로 사용시 주의해야 합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@WebServlet(urlPatterns="/myServlet",
            initParams ={@WebInitParam(name="dbName", value="mydb"),
                         @WebInitParam(name="dbPasswd", value="myPasswd")
            })
public class MyServlet extends HttpServlet{
    
    @Override
    public void init(ServletConfig config) throws ServletException {
        String dbNm = config.getInitParameter("dbName"); //mydb
        String dbPasswd = config.getInitParameter("dbPasswd"); //myPasswd
        
        System.out.println(dbNm);
        System.out.println(dbPasswd);
    }
    
}
cs


web.xml에 한글이 들어갈때 설정방법
초기화 파라미터를 설정할 때라든지 web.xml에 한글이 들어가야 하는 경우가 있습니다.
기본 설정으로는 한글을 인식하지 못해 오류가 발생하기 때문에 다음과 같이 가장 첫줄처럼 <?xml> 태그의 encoding 속성값에 한글코드를 넣어줘야 합니다.
1
2
3
4
5
6
7
<?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/javaeehttp://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd";
    id="WebApp_ID" version="3.1">
    ..내용생략..
</web-app>
cs


ServletConfig 서블릿 초기화 이후 사용 방법
GenericServlet은 Servlet 인터페이스의 구현체이지만 ServletConfig의 구현체이기도 합니다.
바꿔말하면 ServletConfig에 정의되어 있는 메서드들을 모두 사용할 수 있다는 뜻이기도 합니다.

GenericServlet.java
1
2
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
}
cs

MyServlet.java
1
2
3
4
5
6
7
8
9
public class MyServlet extends HttpServlet{
    
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String dbNm = getInitParameter("dbName");
        String dbPasswd = getInitParameter("dbPasswd");
    }
    
}
cs

init()에서와의 차이점이라고 한다면 초기화시에 사용하느냐 아니면 서블릿 로딩 이후 사용자의 요청을 처리할 때 사용하느냐에 차이입니다.

 

init() 메서드 오버라이딩시 주의할 점
만약 init() 메서드를 오버라이딩 한 이후에 service() 메서드나 doGet() doPost() 등 클라이언트의 요청 처리시 사용할 때에는 다음과 같이 조상 클래스인 GenericServlet의 init 메서드를 호출해 주어야 합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MyServlet extends HttpServlet{
    
    @Override
    public void init(ServletConfig config) throws ServletException {
        //초기화 이후에도 ServletConfig를 사용하고 싶다면
        super.init(config);
    }
    
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String dbNm = getInitParameter("dbName");
        String dbPasswd = getInitParameter("dbPasswd");
        
        System.out.println(dbNm);
        System.out.println(dbPasswd);
    }
    
}
cs

 

그렇지 않으면 NullPointerException이 발생하게 됩니다.

1
2
3
4
5
6
7
java.lang.NullPointerException
    at javax.servlet.GenericServlet.getInitParameter(GenericServlet.java:80)
    at servletStudy.MyServlet.service(MyServlet.java:21)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
cs

 

 

블로그 이미지

도로락

IT, 프로그래밍, 컴퓨터 활용 정보 등을 위한 블로그

댓글을 달아 주세요! 질문 환영합니다!