서블릿이란?
자바 진영에서 웹 어플리케이션을 개발하기 위한 기술 또는 스펙입니다.
이 서블릿 기술은 javaEE 라는 슈퍼스펙 안에 포함된 기술 중 하나입니다.
서블릿 이외에도 javaEE 스펙 안에는 여러가지 기술들이 명세되어 있으니 자세한 사항은 API나 위키를 참고하시기 바랍니다.
서블릿은 사용자(보통 브라우저)의 요청을 멀티스레드 방식으로 처리하며, 요청에 대한 응답을 동적으로 처리할 수 있고 자바 웹 어플리케이션은
최소한 서블릿을 한 개 이상 가지고 있습니다.

HttpServlet의 경우 이름처럼 클라이언트로부터의 HTTP 요청을 받아 처리하여 HTTP 응답하는 역할을 합니다.
이 HttpServlet을 확장할 경우 요청을 처리하는 과정을 원하는대로 제어할 수 있으며 요청을 받고 응답해주는 역할은 WAS가 처리합니다.
(JSP도 결국 서블릿으로서 요청을 처리하며 서블릿이 하나도 없는 웹어플리케이션은 존재 의미가 없는 어플리케이션 입니다. 아무 요청도 처리할 수 없기 때문입니다.)

 

 

서블릿의 장점
최초에 웹어플리케이션을 개발하기 위해서는 CGI(Common Gateway Interface) 라는 기술을 사용했습니다.
그러나 CGI는 클라이언트(또는 브라우저) 에서 요청 할 때마다 프로세스를 생성하여 요청을 처리하였고 당시 웹서버의 하드웨어 사양이 좋지도 않은데다가
자원을 많이 사용하는 프로세스들이 늘어나면 동시에 몇십명만 웹서버(사이트)에 접근해도 서버가 뻗어버리기 일쑤였습니다.

그러나 자바는 경량 프로세스라 불리우는 스레드 기반 환경이었고 당시 객체지향 패러다임이 발전하던 시절이었기 때문에 서블릿은 떠오르는 기술로
각광받게 되었습니다.
프로세스에 비해서 훨씬 자원을 덜 소비했던게 가장 큰 장점이었고 덕분에 서블릿을 이용하여 개발한 웹서버는 CGI를 이용했을 때 보다 훨씬 더 많은
사용자 요청을 처리할 수 있게 되었습니다.


서블릿 스펙
서블릿 스펙에 따르면 서블릿을 작성할 때 다음의 몇가지 규칙을 따라야 합니다.

1. 서블릿은 javax.servlet.Servlet 인터페이스를 구현해야 합니다.

2. javax.servlet.Servlet 인터페이스를 따로 구현할 필요가 없거나 구현하기 힘들다면 미리 구현되어 있는 javax.servlet.http.HttpServlet을 상속합니다.
   (일반 웹 프로그래머들이 직접 Servlet 인터페이스를 구현할 일은 거의 없습니다.)

3. doGet() 이나 doPost() 같은 클라이언트의 요청에 대한 서비스 메서드를 오버라이딩 하고 이때 첫번째 파라미터로 
   javax.servlet.http.HttpServletRequest 와  두번째 파라미터로 javax.servlet.http.HttpServletResponse를 받아야 합니다. (순서도 중요합니다)

4. java.io.IOException 과 javax.servlet.ServletException 예외를 던져야 합니다.

5. web.xml(배포서술자)를 통해 서블릿을 url과 맵핑(연결)시켜줘야 합니다. (서블릿 3.0부터는 필수가 아닌 선택사항입니다.)

6. 서블릿 스펙이라기보다 서블릿 스펙을 포함하고 있는 JavaEE 스펙에는 웹 어플리케이션의 디렉터리 구조를 다음과 같이 제시하고 있습니다.
   이 디렉터리 구조는 J2EE 스펙을 구현한 WAS에서 인식할 수 있는 표준 구조입니다.
   i18n의 경우에는 스펙은 아니지만 L10n(지역화) 와 같이 관례적으로 포함되는 디렉터리입니다.

 

더 많은 규칙들이 명세되어 있지만 크게는 이정도 입니다.



서블릿 작성
규칙에 따라 간단한 서블릿을 작성해보겠습니다.
여기서는 서블릿에 대한 큰 흐름만 파악하고 이후 포스팅들을 통해 깊이 있게 알아보겠습니다.

 

 

MyServlet.java

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
44
45
46
47
48
49
50
51
package controller;
 
import java.io.IOException;
import java.io.PrintWriter;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class MyServlet extends HttpServlet {
 
     private int visitCount = 0;
 
     @Override
     public void init() throws ServletException {
           System.out.println("서블릿이 초기화 되었습니다.");
     }
 
     @Override
     protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
 
           this.visitCount++;
 
           response.setContentType("text/html; charset=utf-8");
 
           PrintWriter out = response.getWriter();
 
           out.println("<HTML>");
           out.println("<head><title>테스트</title></head>");
           out.println("<body>");
           out.println("이것은 서블릿!! 방문자 : " + this.visitCount);
           out.println("</HTML>");
 
     }
 
     @Override
     protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
           doGet(request, response);
           //또는 post로 요청이 왔을때 해야 할 일
           //현재 로직상 post로 요청해도 바로 doGet 메서드를 호출함
     }
 
     @Override
     public void destroy() {
           System.out.println("서블릿이 소멸됩니다.");
     }
 
}
cs

 

 

 

코드 설명
init() 메서드는 최초 서블릿 객체가 생성된 후 초기화 될 때 호출되는 메서드 입니다.
서블릿이 초기화 될 때 콘솔로 "서블릿이 초기화 되었습니다." 라는 문자열을 출력합니다.
콘솔 출력의 경우 보통 현업에서는 리눅스 서버를 많이 사용하므로 리눅스 서버의 터미널창에 서블릿이 초기화 될 때 문구가 출력될 것입니다.

doGet() 메서드는 클라이언트에서 GET 방식으로 요청을 보냈을 때
호출되는 메서드 입니다.

이 때 클라이언트에 대한 정보나 요청에 관련된 정보들은 첫 번째 파라미터로 받은 HttpServletRequest 객체에 담겨있고,
클라이언트에 다시 응답을 보낼 때에는 HttpServletResponse 객체를 사용하면 됩니다.

HttpServletResponse의 setContentType() 메서드를 통해 지금부터 클라이언트(브라우저) 에게 보낼 내용은 html 문자열이고 인코딩은 utf-8이야 라는
정보를 세팅해 주었습니다.

특히 HttpServletResponse 객체의 getWriter() 메서드를 통해 클라이언트로 무언가를 출력할 수 있는 스트림(통로)를 얻을 수 있습니다.
그 스트림은 java.io.PrintWriter 객체이고 PrintWriter 의 print() 또는 println() 메서드 등을 이용해 결과를 출력하면 됩니다.
보통 자바를 배울 때 PrintWriter는 파일 출력에 사용했지만 서블릿에서는 데이터를 브라우저로 출력할 때 사용합니다.

여기서는 HTML 마크업 태그를 문자열로 출력하고 있습니다.
결과를 받은 클라이언트 즉 브라우저는 스크림을 통해 받은 출력 결과 문자열이 html 문자열이라는 것을 판단 후 해당 태그들을 해석하여
사용자에게 화면을 그려줄 것입니다.

doPost() 메서드는 post 방식으로 요청이 왔을 때 호출되며 여기서는 호출 되자마자 바로 doGet()을 호출하며 HttpServletRequest, HttpServletResponse 
객체를 전달하고 있습니다.

destroy()메서드는 해당 서블릿이 소멸될 때 호출되는 메서드 입니다.

참고!) @Override 애너테이션을 모르시는 분들이 있을텐데 이 애너테이션은 자바 컴파일러용 주석이라고 생각하면 되는데 해당 메서드가 오버라이드 되었다는 것을 알리기 위한 애너테이션 입니다.


배포서술자 작성
서블릿을 작성한 후에는 해당 서블릿을 사용자가 요청한 경로와 맵핑 시켜줘야 합니다.
그러면 WAS(예를 들어 톰캣)이 맵핑 정보를 읽어서 브라우저에서 해당 URL로 HTTP 요청 시 해당 서블릿으로 요청을 전달해 주는 것 입니다.

web.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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"
     version="3.1">
 
     <servlet>
           <servlet-name>myServlet</servlet-name>
           <servlet-class>controller.MyServlet</servlet-class>
     </servlet>
 
     <servlet-mapping>
           <servlet-name>myServlet</servlet-name>
           <url-pattern>/myServlet</url-pattern>
     </servlet-mapping>
 
</web-app>
 
cs

 

 

 

코드설명
첫줄에 이것이 xml 문서라는 것과 어떤 캐릭터 셋으로 작성되었는지 알려줍니다.
두 번째 줄부터 있는 <web-app> 태그는 배포서술자의 root 엘리먼트이며 그 안의 속성들을 통해 현재 웹 어플리케이션이 서블릿 api 3.1을 사용하고 있음을 알려줍니다.
root 엘리먼트 밑으로는 서블릿 맵핑같은 웹 어플리케이션 설정들이 들어갑니다.

<servlet> 엘리먼트는 서블릿에 대한 정보가 들어갑니다.
<servlet-name>은 쉽게 서블릿을 참조할 수 있는 이름이라고 보면 됩니다. 여기서는 myServlet이라고 등록했습니다.
<servlet-class>서블릿 클래스의 위치를 알려줍니다. 예를 들어 톰캣/webapps/웹어플리케이션루트/classes/controller/MyServlet.class 가 서블릿의 경로일 경우
위 코드처럼 controller.MyServlet을 등록해줍니다.

<servlet-mapping> 서블릿과 URL 맵핑정보입니다.
<servlet-name> 위에서 설정한 myServlet을 맵핑시켜줍니다.
<url-pattern> URL 패턴을 등록하는데 /myServlet으로 등록한 경우 http://서버주소:포트번호/웹어플리케이션이름/myServlet 으로 맵핑되며 
해당 URL을 브라우저에서 입력한 경우 WAS(예를 들어 톰캣)가 myServlet으로 요청을 전달해줄 것입니다.


결과 화면
저는 웹어플리케이션 루트 경로를 ROOT 즉 "/" 로 설정했기 때문에 http://localhost:8080/myServlet으로 요청했습니다.
URL을 요청할 때마다 방문자 수가 증가합니다.

 

 

 

 

블로그 이미지

도로락

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

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