본문 바로가기

Study/BackEnd

[BackEnd] Servlet 실습 & LifeCycle

Client가 Server에 무언가 요청을 한다면 그 결과를 Client에게 보여줄 수 있어야 한다.

요청 결과인 응답은 html형태가 되는데 이를 ServletResponse 인터페이스에서 담당한다.

ServletResponse안에는 PrintWriter라는 클래스 타입으로 반환하는 getWriter() 메소드가 존재한다

이를 이용하여 java파일 안에서 html을 반환시키는 출력 객체를 만들어 반환할 수 있게 된다.

package practice.helloservlet;

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 HelloServlet
 */
@WebServlet("/Hello")
public class HelloServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           response.setContentType("text/html;charset=utf-8");
        PrintWriter out= response.getWriter();
        out.println("<html>");
        out.println("    <body>");
        out.println("        HelloServlet");
        out.println("    </body>");
        out.println("</html>");
    }
}

위 소스코드를 실행시키면 웹페이지가 실행되면서 "HelloServlet"이라는 글이 출력되어 있을 것이다.

23번 라인의 setContentType 메소드는 인코딩을 의미한다.

text/html이 의마하는 것은 server는 text를 보낼테니 client는 html로 인식하라는 것을 의미하고

charset=utf-8은 인코딩을 의미한다. 이 코드가 있어야 한글을 포함한 모든 언어를 인식할 수 있다.

doGet 메소드나 doPost메소드는 클라이언트의 요청을 처리하는 메소드 라고 했는데

꼭 처리해야할 로직이 3가지가 있다.

  1. client로부터 넘어온 data(parameter) 처리
  2. 비즈니스 로직 처리 & DataBase 로직 처리
  3. 화면 출력을 위한 response 처리

보통 하나의 페이지에서 여러가지의 동작을 수행하도록 만들기 때문에 각각의 요청에 대해 새로운 메소드를 만들어 처리하게 될 것이다.


하나 알아둬야 할 점은 위와 같은 소스코드는 잘 사용하지 않는다.

out.println("~~")같은 방식은 html 내용안에 큰따옴표가 존재하면 모든 큰따옴표에 백슬래쉬(\)를 붙여줘야 동작하게 된다. java안에서 html을 사용하기 때문에 발생하는 번거로움인데 이를 간편하게 사용하기 위해 jsp를 사용한다.

jsp는 html안에서 java를 사용할 수 잇도록 만든것인데 <% %>등의 태그를 사용하면 html과 함께 java문법을 좀더 간편하게 사용할 수 있다.


Servlet의 Life Cycle

Servlet class는 main method가 존재하지 않는다.

객체의 생성부터 사용의 주체는 사용자가 아닌 Servlet Container에게 있다.

Client가 request하면 Servlet Container는 Servlet객체를 한번만 생성하고 초기화하며

이후 요청시마다 그에대한 처리 메소드를 반복한다.

Servlet객체가 필요 없게되면 제거하는 일도 Container가 담당하는데 이 때 destroy() 메소드가 호출된다.

@WebServlet("/Hello")
public class HelloServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out= response.getWriter();
        out.println("<html>");
        out.println("    <body>");
        out.println("        HelloServlet");
        out.println("    </body>");
        out.println("</html>");
        System.out.println("doGet() method call!!");
    }

    @Override
    public void destroy() {
        System.out.println("destroy() method call!!");
    }

    @Override
    public void init() throws ServletException {
        System.out.println("init() method call!!");
    } 
}

이처럼 메소드가 호출될 때 마다 콘솔에 해당 메소드를 출력하도록 코드를 작성 해 보았다.

프로젝트를 실행하면 init메소드를 한번만 실행할 것이고 이후 페이지를 호출할 때 마다 doGet메소드를 실행할 것이다. 이후 현재 메모리에 적재된 프로그램이 필요 없어질 때 destroy 메소드를 호출하고 종료될 것이다.