Servlet - 2

김민석·2021년 1월 28일
0

웹 프로그래밍 - be

목록 보기
3/6
post-custom-banner

서블릿 LifeCycle

LifeCycle(생명주기) : 어떤 객체의 생성부터 소멸까지의 과정

Servlet 생명주기 메서드 종류

init()
서블릿이 작업하는데 필요한 자원을 준비시킨다.
destroy()
서블릿이 사용한 자원을 초기화 시킨다.
service()
클라이언트가 요청한 작업을 처리한다.

생명주기

1. WAS가 서블릿의 요청을 받으면 서블릿이 메모리에 있는지 없는지 확인한다.
2. 만약 메모리에 없으면 서블릿 클래스를 메모리에 올리는 작업 후(객체 생성) init 메서드를 호출한다.
3. 메모리에 있으면 service 메서드를 호출한다.
4. WAS가 종료되거나 웹 어플리케이션이 수정되면 destroy 메서드를 호출한다.

예제

그림과 같이 생성자와 init, destroy, service 메서드를 구현 후 실행해 보면 콘솔창에서 다음과 같은 결과를 확인할 수 있다.

그리고 새로고침이나 다른 브라우저에서 해당 URL을 열었을 때 다음과 같이 service 메서드 부분만 실행되는 것을 확인할 수 있다.

init 메서드를 수정하면 다음과 같은 결과가 나오는 것을 확인할 수 있다.

위의 예제들을 통해 생명주기를 확인할 수 있다. 우선 처음 서블릿이 실행되면 메모리에 없기 때문에 생성자, init 실행 후 service가 실행되며, 새로고침을 했을 때는 이미 서블릿이 메모리에 존재하기 때문에 service만 실행되는 것을 확인할 수 있다. 또한 웹 어플리케이션이 수정되었을 때 destroy가 실행된 것을 확인할 수 있다.

코드

package example;

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

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

import org.apache.catalina.connector.Response;

@WebServlet("/LifecycleServlet")
public class LifecycleServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
    public LifecycleServlet() {
        System.out.println("LifecycleServlet 생성!");
        
    }
	public void init(ServletConfig config) throws ServletException {
		System.out.println("init 수정!");
	}
	public void destroy() {
		System.out.println("destroy 호출!");
	}
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("service 호출!");
	}
}

일반적으로 서블릿 작성은 위의 예제처럼 service를 직접 구현하는 것 보다는 HttpServlet의 service 메서드를 상속받아 사용한다. HttpServlet의 service 메서드는 템플릿 메서드 패턴으로 구현하는데, 클라이언트의 요청이 GET일 경우 자신이 가지고 있는 doGet메서드를 호출하고, 클라이언트의 요청이 POST일 경우 자신이 가지고 있는 doPost메서드를 호출한다. doGet은 보통 URL에 직접 요청할 때 사용된다.

예제
위에서 사용했던 코드에서 service부분을 주석처리하고, doGet()과 doPost()를 오버라이딩 해 보았다.
(오라클 상단 탭의 source -> Override/Implement Methods에서 오버라이딩 할 수 있다.)

그림과 같이 메서드들을 구성해 주고 실행하면 다음과 같은 결과를 얻는다.

name에 입력한 결과는 아래와 같다.

우선 doGet메서드는 앞서 언급했듯이 URL을 통해 직접 접근할 때 사용되는 것으로 doGet메서드에 기입된 html 코드에 맞게 결과가 나오는 것을 확인할 수 있다.

doGet메서드의 html 코드들을 살펴보면 form 태그 부분을 볼 수 있다. form 태그는 웹 페이지에서의 입력 양식을 의미하며 input으로 들어온 값을 백엔드 서버에 전달하는 역할을 하는 태그이다. 코드를 제대로 살펴보면 form 태그의 속성들로 method와 action을 볼 수 있는데, method는 폼 전송 방식을 택하는 속성으로 예제에서는 'post'로 해 주었다. action은 폼 데이터가 전송되는 백엔드 url을 의미한다. 즉, 해당 url로 정보들을 보내는데, post 방식을 사용하기 때문에 doPost메서드가 호출되는 것이다. 따라서 name에 값을 입력했을 때 위와 같은 결과를 보이게 된 것이다. name 값을 넘겨주는 방식으로는 form 태그 내부의 input 태그를 활용한 것인데, name 속성을 통해 데이터의 이름을 정해 준 후 getParameter를 통해 해당 이름을 가진 데이터를 가져와 사용한 것이다.

코드

package example;

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

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

import org.apache.catalina.connector.Response;

@WebServlet("/LifecycleServlet")
public class LifecycleServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
    public LifecycleServlet() {
        System.out.println("LifecycleServlet 생성!");
        
    }
	public void init(ServletConfig config) throws ServletException {
		System.out.println("init 수정!");
	}
	public void destroy() {
		System.out.println("destroy 호출!");
	}
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("text/html");
		PrintWriter out = resp.getWriter();
		out.println("<html>");
		out.println("<head><title>form</title></head>");
		out.println("<body>");
		out.println("<form method='post' action='/firstweb/LifecycleServlet'>");
		out.println("name : <input type='text' name='name'><br>");
		out.println("<input type='submit' value='ok'><br>");                                                 
		out.println("</form>");
		out.println("</body>");
		out.println("</html>");
		out.close();
		
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.setContentType("text/html");
		PrintWriter out = resp.getWriter();
		String name = req.getParameter("name");
		out.println("<h1>hello " + name + "</h1>");
		out.close();
	}
}

위의 예제를 통해 같은 URL이라도 GET 방식이냐 POST 방식이냐에 따라 다른 결과를 보이는 것을 알 수 있다.

출처 : 부스트코스 웹 프로그래밍(풀스택)
https://www.boostcourse.org/web316/lecture/254273

profile
김민석의 학습 정리 블로그
post-custom-banner

0개의 댓글