본문 바로가기
Back-end

서블릿(Servlet)

by 신재권 2021. 8. 8.

서블릿은 Java를 이용하여 동적 웹 서비스를 구현한 기술로 JSP보다 먼저 발표되었다. 서블릿을 제작한다는 것은 웹 서비스를 제공하기 위한 Java클래스를 제작하는 작업이며 제작하기 위해 지켜야 하는 몇몇 규칙이 있다.

서블릿의 개요

서블릿은 동적 웹 서비스를 Java로 구현하기 위한 기술로, 서버(Server) 측 자바 응용프로그램(Applet)이라는 의미의 단어들을 결합한 명칭인 'Servlet'으로 발표되었다. 이는 웹 클라이언트의 요청을 처리하여 응답하기 위해 웹 서버에서 실행되는 Java 클래스를 의미한다. 따라서 서블릿 역시 Java의 다양한 API 및 객체지향 프로그래밍의 장점을 그대로 활용할 수 있다.

서블릿과 서블릿 컨테이너

서블릿은 Java 클래스이므로 웹 서비스를 구현하기 위해서 기본적으로 JDK가 필요하다. 또한 서블릿이 웹 클라이언트 요청에 따라 응답처리를 하기 위해서는 서블릿의 수행을 유지 및 관리해줄 수 있는 특별한 프로그램인 서블릿 컨테이너(Servlet Container)가 필요한데, 톰캣이 그 기능을 제공한다.

(1) 서블릿과 서블릿 컨테이너의 동작과정

웹 클라이언트의 요청을 처리할 서블릿의 동작에 관여하는 서블릿 컨테이너의 역할은 간단히 다음과 같이 표현할 수 있다.

  • 실행을 위한 서블릿이 담겨 있는 용기
  • 서블릿 객체를 보관
  • 보관되어 있는 서블릿 객체를 관리하여 서비스

이러한 서블릿 컨테이너를 통한 서블릿의 동작 진행은 아래와 같이 이루어 진다.

  1. 웹 클라이언트에서 전송된 HTTP 요청을 웹 서버가 전달 받음
  2. 웹 서버는 HTTP 요청 정보를 묶어 서블릿 컨테이너에 전달
  3. 서블릿 컨테이너는 저장된 서블릿 객체들 중 해당 HTTP 요청을 처리할 수 있는 서블릿을 실행
  4. 웹 서버에서는 서블릿 실행을 통해 만들어진 응답을 전달받음
  5. 웹 서버는 전달받은 응답을 웹 클라이언트에게 전송

웹 서버를 통해 요청 정보를 전달받았을 때 서블릿 컨테이너의 내부 동작을 조금 더 살펴보자. 아래는 서블릿 컨테이너가 전달받은 요청 정보로부터 서블릿의 실행 및 결과를 웹 서버에 전달하기까지의 과정을 나타내고 있다.

  1. 웹 서버의 요청(request) 정보를 통해 HttpServletRequest 클래스의 객체인 요청 객체와 HttpServletResponse 클래스의 객체인 응답 객체를 생성
  2. 전달받은 요청을 처리할 수 있는 서블릿 클래스가 서블릿 컨테이너에 로딩되어 있는지 검사
  • 로딩되어 있지 않을 경우 해당 서블릿 클래스를 로딩하여 객체를 생성
  • 이미 로딩되어 있을 경우 해당 서블릿 클래스의 객체를 생성
  1. 생성과 서블릿 객체를 호출하여 실행, 실행 시 doGet 혹은 doPost 메서드에 필요한 입력 파라미터는 1,2 과정에서 생성된 HttpServletRequest, HttpServeltResponse 클래스의 객체를 이용.
  2. 서블릿 실행 결과를 웹 서버에서 전달

위 과정에서 HttpServletRequest 객체는 요청 정보를 담기 위해 사용하며, HttpServletResponse 객체는 요청에 대한 응답 정보를 지정하기 위해 사용된다. 이 두 객체는 서블릿 클래스 내부에서 요청을 처리할 코드가 포함된 doGet()/doPost() 메서드의 입력 파라미터로 사용되어 메서드 내부에서 요청 및 응답 정보로 활용될 것이다.

(2) 서블릿의 생명주기

서블릿의 생명주기란 서블릿 컨테이너가 요청을 전달받았을 때 진행되는 서블릿 클래스의 로딩, 서블릿 객체 생성, 서블릿 객체의 사용 및 소멸에 이르는 과정을 의미한다. 서블릿 컨테이너에 의해 아래 세가지 메서드가 상황에 따라 호출되어 진행된다.


init : 서블릿이 처음 인스턴스화될 때 최초 한 번만 호출되는 메서드로 이후의 요청 처리는 스레드를 통한 service메서드의 호출로 진행

service : 서블릿에 대한 요청이 있을 때 호출되는 메서드, 웹 클라이언트의 요청이 있을 때마다 반복 실행되며 요청 방식의 종류에 따라 doGet, doPost 메서드를 자동으로 호출

destroy : 서블릿 인스턴스가 더 이상 서비스를 하지 않을 경우 메모리에서 제거하기 위해 호출되는 메서드, 호출 후 자바의 Garbage Collector가 인스턴스를 메모리에서 제고


서블릿 클래스의 작성방법

자바를 사용하여 동적 웹 서비스를 구현하는 기술인 서블릿을 구현한다는 것은 Java클래스를 제작한다는 의미지만 일반 Java클래스와 달리, 구현 시 특정한 구성과 구현 규칙을 지켜야 한다.

 

(1)HttpServlet 클래스 상속

서블릿 클래스 작성 시 클래스는 pulbic으로 선언되어야 하며 반드시 HttpServlet 클래스를 상속하여야 한다.

HttpServlet 클래스는 HTTP 프로토콜에 최적화된 서블릿 구현을 위한 클래로 GenericServlet 클래스를 상속받는 추상 클래스이며, GenericServlet 클래스는 ServletConfig와 Servlet, Serializable 인터페이스를 구현하는 클래스이다.

GenericServlet 클래스는 일반적으로 네트워크 프로토콜 전반에 사용될 수 있는 서블릿을 제작하기 위한 기능들로 구성되어 있으며, 우리가 서블릿 클래스를 통해 구현할 웹 애플리케이션은 HTTP 프로토콜을 이용하므로 HTTP 프로토콜에 최적화된 서블릿구현을 위해 제작된 클래스인 HttpServlet 클래스를 서블릿 클래스에 상속받는다.

Servlet : 서블릿 기능 관련 메서드들을 정의한 인터페이스로 서블릿의 생명주기(Life Cycle) 관리에 필요한 init, service, destroy 메서드 등을 정의

ServletConfig : 서블릿과 관련된 초기화 정보 처리에 필요한 메서드를 정의한 인터페이스

java.io.Serializable : 바이트 단위의 변환으로 파일, 네트워크를 통해 객체 내용의 송수신이 가능하게 만들어 주는 객체 직렬화 인터페이스로, 서블릿 객체의 직렬화를 위해 사용

Servlet과 ServletConfig 인터페이스는 서블릿 통신 구현에 필요한 기본적인 메서드들을 정의해 놓았고 이들을 GenericServlet이 구현하고 있다.

 

(2) doGet/doPost 메서드 구현

서블릿 클래스를 제작할 때 웹 프로그래머가 직접 구현해야 하는 부분은 doGet메서드 및 doPost 메서드이다. 웹 클라이언트의 전송 요청 방식이 get방식인지 post방식인지 여부에 따라 service 메서드 내부에서 호출될 doGet 혹은 doPost 메서드를 재정의(overriding)해야 하며 각 메서드는 다음과 같이 서블릿 컨테이너에 의해 가공된 HttpServletRequest와 HttpServletResponse 타입의 입력 파라미터를 사용하여 요청 및 응답 정보를 활용하게 된다.


Servlet 구현 부분

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class Join
 */
@WebServlet("/Join")//@WebServlet : 이 주소로 요청이 오면 이 클래스가 처리하겠다
public class Join extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Join() {
        super();
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// get 방식 처리
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//post 방식 처리 
		//인코딩 설정 
		request.setCharacterEncoding("utf-8");  //요청정보의 인코딩 
		response.setContentType("text/html; charset=utf-8"); //응답할 정보의 인코딩
		

		PrintWriter out = response.getWriter();
		String name = request.getParameter("name"); 
		String sex = request.getParameter("sex"); 
		String[] hobby = request.getParameterValues("hobby");
		
		out.println("<html>");
		out.println("<body>");
		out.println("<h2>작성하신 내용은 다음과 같습니다.</h2><br/>");
		out.println("이름 : "+name);
		out.println("<hr>");
		out.println("성별 : "+sex);
		out.println("<hr>");
		out.println("아이디 : "+id);
		out.println("<hr>");
		out.println("주소 : "+address);
		out.println("<hr>");
		out.println("이메일 주소 : "+email);
		out.println("<hr>");
		out.println("<table border=\"1\">");
		if(hobby == null){
			out.println("[선택한 취미가 없습니다.]");
		}else{
			out.println("<table border=\"1\">");
			for(int i=0; i<hobby.length; i++){
				out.println("<tr>");
				out.println("	<td>");
				out.println(hobby[i]);
				out.println("	</td>");
				out.println("</tr>");
			}
			out.println("</table>");
		}
		
		out.println("</body>");
		out.println("</html>");
	}

}

HTTP 요청은 별다른 방식 지정이 없다면 기본 요청 방식은 GET이다.

HTTP 요청에 함께 사용되는 파라미터 값은 숫자처럼 보여도 데이터 타입은 문자열

@WebServlet : 이 주소로 요청이 오면 이 클래스가 처리하겠다

getParameter : name속성에 있는 값이 파라미터의 이름이다.

getParameter : 단일값 getParameterValues : 다중값

request.setCharacterEncoding("utf-8"); //요청정보의 인코딩 response.setContentType("text/html; charset=utf-8"); //응답할 정보의 인코딩

'Back-end' 카테고리의 다른 글

Spring 용어정리 (1)  (0) 2021.08.10
Spring Concept  (0) 2021.08.09
웹 프로그래밍  (0) 2021.08.07
SQL 문법 (4)  (0) 2021.08.01
SQL문법 (3)  (0) 2021.07.25