Servlet JSP MVC Spring

[Servlet] 서블릿(servlet) 이해하기

vhxpffltm 2020. 2. 4. 21:20

서블릿이란

 

서버에서 실행되다 웹 브라우저에서 요청을 하면 해당 기능을 수행한 후 웹 브라우저에 결과를 전송하며

 

서버에서 실행되므로 보안과 관련된 기능도 안전하게 수행한다.

 

즉, 클라이언트의 요청이 오면 기능을 수행하고 그 결과를 웹 브라우저에 돌려준다고 생각하면 된다. 동적으로 여러 기능을 제공하며 스레드 방식과 자바의 객체 지향적 특징을 가진다.

 

아래 그림은 서블릿 관련 클래스들의 계층 구조이다.

 

 

Servlet 인터페이스는 Servlet관련 추상 메서드를 선언하며 init(), service() 등을 선언한다. -> javax.servlet

ServletConfig 인터페이스는 Servlet 기능 관련 추상 메서드가 선언되어 있다. ->javax.servlet

GenericServlet 은 상위 두 인터페이스를 구현하며 일잔적 서블릿 기능을 구현한 클래스이다.

->javax.servlet

HttpServlet은 HTTP 프로토콜을 사용하는 웹 브라우저에서 서블릿 기능을 수행한다 -> javax.servlet.http

 

다양한 메서드들이 있지만, 이제 서블릿의 간단한 생명주기 메서드를 해보며 어떻게 코드가 돌아가는지 이해해보자.

먼저 프로젝트를 만든다. 'dynamic web project'를 만들고 이름은 아무거나 하자 

 

 

다음으로 프로젝트를 오른쪽 클릭하여 Java Build Path를 설정한다. LibrariesClasspathAdd External JARs를 눌러 우리가 설치한 톰캣 경로의 lib 폴더에 가면 아래 그림과 같은 jar 파일이 있다. 이것을 추가한다.

 

 

이렇게 했으면 코드를 간단하게 입력하기 전에 설정한 프로젝트를 톰캣에 연동시키자. servers탭에서 이전에 진행했던 대로 톰캣에 추가하면 된다. 아래 그림체 추가한 프로젝트를 확인할 수 있다. 

 

그렇다면 이제 JSP를 간단하게 알아볼 코드를 짜보자. 자바 코드는 Java Resources/src/에 먼저 패키지를 추가하고 그 아래에 자바 클래스를 만들것이다. 아래 그림과 같이 말이다. 하나씩 보겠지만 3개의 클래스를 원하는대로 생성하면 된다.

 

 

FirstServle.java를 보자 코드는 아래와 같다. SecondServelt.java 도 아래와 같으며 출력 println 내용만 다르다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package sec01.ex01;
 
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
 
public class FirstServlet extends HttpServlet{ //HTTPServlet을 상속
@Override
  public void init() throws ServletException{
    System.out.println("init 메서드 호출");
    }
@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException{
    System.out.println("doGet 메서드 호출");
}//브라우저의 요청을 처리
 
@Override
public void destroy() {
    System.out.println();
 }
}
//HttpServlet 을 상속받고 3개의 생명주기 메서드를 차례로 구현 -> 그저 메시지 출력
/*서블릿 매핑과정
1) 각 프로젝트에서 web.xml에서 설정
2) <servlet> 태그와 <servlet-mapping> 태그를 이용 -> 여러개일땐 <servlet> 부터 정의하고 다음에 <servlet-mapping> 적용
 */ 
 
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

위와 같이 코드를 작성한다. 간단하게 init() -> doGet() -> destroy() 함수를 나타내며 각 함수들은 메세지 출력만을 나타낸다.

init는 서블릿 요청시 맨 처음 한 번만 호출되고 doGet() 메서드는 요청 시 매번 호출되며 실제로 클라이언트가 요청하는 작업을 수행한다. destroy()는 메모리에서 소멸될 때 호출된다. 

 

이렇게 클래스를 작성하고 이번에는 web.xml을 아래와 같이 수정한다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8"?>
  <servlet> <!--  브라우저에 요청하는 매핑이름에 대해 실제로 실행하는 서블릿 클래스를 설정하는 태그 -->
    <servlet-name>aaa</servlet-name> <!-- servlet-mapping 태그의 <servlet-name> 태그와 값이 동일 -->
    <servlet-class>sec01.ex01.FirstServlet</servlet-class> <!-- 브라우저에서 요청하는 매핑이름에 대해 실제로 기능을 수행하는 서블릿 클래스 설정 -->
  </servlet>
  <servlet>
    <servlet-name>bbb</servlet-name> <!-- 이 값은 다른 <servlet-name> 태그 값과 같으면 안됨 -->
    <servlet-class>sec01.ex01.SecondServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>aaa</servlet-name> <!-- 매핑이름으로 요청시 값이 같은<servlet> 태그안의 같은 <servlet-name> 태그와 연결 -->
    <url-pattern>/first</url-pattern><!-- 브라우저에서 클래스 이름(sec01.ex01.Fir..)을 요청하는 논리적인 서블릿 이름 -->
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>bbb</servlet-name>
    <url-pattern>/second</url-pattern>
  </servlet-mapping>
  
</web-app>
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

 

전체 코드가 있는데 각 태그별 내용은 옆에 주석으로 간단히 표시하였다. <servlet-name> 태그의

서블릿 매핑은 <servlet> 태그와 <servlet-mapping> 태그의 하위태그에 <servlet-name> 태그가 공통으로 존재한다. 

<servlet-name> 태그의 값 aaa가 <servlet>과 <servlet-mapping> 태그를 연결시켜준다.

 

웹 브라우저에서는 <url-pattern> 태그의 /'이름' 으로 요청할 경우 aaa값을 가지는 <servlet> 태그를 찾아 실제 서블릿인 sec01.ex01.FirstServlet을 실행한다.

 

그렇다면 아래의 bbb 이름을 가지는 태그는? 당연히 다른 서블릿을 실행하기 위해 있는 코드이다.

 

톰캣을 실행하고 웹 브라우저에 localhost:[포트번호]/'프로젝트명'/서블릿명  을 입력하면 아래와 같은 출력 결과를 얻을 수 있다.

 

애너테이션을 이용한 서블릿 매핑

 

마지막으로 편리한 코드작성을 해보자. 각 서블릿 클래스에 기호를 이용하여 서블릿을 표시하면 가독성 좋게 사용할 수 있다.

 

애너테이션을 이용하려면 서블릿 클래스에 @WebServlet을 이용하면 된다. 아래 코드를 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package sec01.ex01;
 
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
 
/**
 * Servlet implementation class thirdServlet
 */
@WebServlet("/third"//애너테이션에 수정한 매핑이름이 추가 -> web.xml에 수동으로 작업할 필요가 없다.
public class thirdServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    //서블릿 클래스 직렬화를 위해 이클립스에서 자동으로 지정한 상수
    /**
     * @see Servlet#init(ServletConfig)
     */
    public void init(ServletConfig config) throws ServletException {
        // TODO Auto-generated method stub
        System.out.println("third init() 메서드");
    }
 
    /**
     * @see Servlet#destroy()
     */
    public void destroy() {
        // TODO Auto-generated method stub
        System.out.println("third destroy() 메서드");
    }
 
    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        System.out.println("third deGet() 메서드");
    }
    //애너테이션을 사용할때는 매핑 이름이 이미 사용된 다른 매핑 이른과 중복되지 않도록 주의
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
 

 

파일을 생성할 때, 클래스가 아니라 servlet으로 생성하면 바로 적용할 수 있다. class name에 파일 이름을 입력하고 다음으로 넘어가 URL mapping에 웹 브라우저에서 접속할 URL이름을 입력한다. 다음 생명주기 메서드 오버라이딩을 적용하는데 필요한 메서드를 선택하여 생성하면 위와 같은 코드를 바로 얻을 수 있다.

 

코드에 @WebServlet으로 애너테이션 코드가 보인다. 이것을 통해 웹 브라우저에서 바로 요청할 수 있다. 단 주의할 점은 web.xml의 매핑 이름과 중복되어서는 안된다.

 

 

 

 

Refernce

자바 웹을 다루는 기술<길벗>