Web/Java+Spring

Servlet의 Life Cycle

WakaraNai 2021. 5. 5. 21:17
728x90
반응형

LifecycleServlet 클래스를 생성하여 어떤 식으로 어떤 메소드가 실행되는지 확인해보겠습니다.

 

처음 생성했던 프로젝트인 firstWeb에서 examples 패키지에 LifecycleSerblet 클래스 파일을 생성해줍니다.

이 때 오버라이드할 메소드는 다음과 같습니다.

각각의 메소드가 어떤 순서로 실행되는지 확인해보려 합니다.

 

HttpServlet의 3가지 메소드를 오버라이딩

  • init()
  • service(request, response)
  • destroy()

 

 

생성자

클라이언트가 해당 url로 요청하여, 서버는 그 url을 받아서 LifecycleClass를 실행했습니다.

당연히 메모리 LifecycleClass의 객체가 없을 테니 먼저 그 객체를 생성해야합니다.

그래서 생성자가 먼저 실행됩니다.

 

init()

생성자 이후에 실행됩니다.

 

 

service()

새로고침을 하면 할 수록 service()메소드만 그 횟수만큼 생성됩니다.

새로고침은 새로운 요청이기 때문입니다.

 

Servlet은 서버에 servlet 객체를 여러 개 만들지 않습니다. (생성자가 한 번만 생기죠)

요청이 여러번 들어오면 요청된 객체가 메모리에 존재하는지 확인 후 있다면 service()만 계속 실행시킵니다.

 

 

 

destroy()

init() 속 print()문을 수정하여 다시 새로고침합니다.

그럼 이전에 쓴 servlet 객체는 더 이상 사용될 수 없습니다.

이 때 destroy() 메소드가 실행됩니다.

다시 새로고침 해보면 수정된 init() 메세지가 뜹니다. 

destory()는 과거의 servlet 객체를 제거해주는 역할을 합니다.

 

 

 

 

 

 

 

 

 

 

Servlet Life Cycle

 

  1. WAS는 Servlet 요청을 받으면 해당 servlet이 메모리에 있는 지 확인
  2. 메모리에 있으면
    1. 해당 servlet 클래스를 메모리에 올림 (객체생성-생성자)
    2. init() 메소드 실행
  3. 없으면
    1. service() 메소드 실행
  4. WAS가 종료되거나, 웹 어플리케이션이 새롭게 갱신되면 destroy() 메소드 실행

 

 

service(request, response) 메소드

내가 만든 클래스가 service() 메소드를 포함하지 않으면, 나의 부모 클래스의 service() 메소드가 실행됨.

그러니까 HelloServlet.java를 만들었을 때는 doGet()이라는 메소드만 오버라이드 했고

이 service() 메소드는 오버라이드 하지 않았습니다.

그런데 WAS는 매번 service()만 호출합니다. 오버라이드 하지 않았는데도요.

그 이유는 servlet의 부모인 HttpServlet의 service() 메소드가 실행됐습니다.

  • HttpServlet의 service()  메소드는 템플릿 메소드 패턴으로 구현되어있습니다.
    • 클라이언트 요청이 GET이면, 자신이 가지고 있떤 doGet(request, response) 메소드 호출
    • 클라이언트 요청이 POST이면, 자신이 가지고 있떤 doPOST(request, response) 메소드 호출

 

doGet() 메소드를 실행하려면 다음과 같이 해봅시다.

일단 service()를 주석처리합니다

이후에는 Source -> Override/Implement Methods -> doGet(), doPost() 선택 -> OK

 

 

코드는 다음과 같이 수정해줍니다.

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//super.doGet(req, resp);
		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 {
		// TODO Auto-generated method stub
		//super.doPost(req, resp);
		resp.setContentType("text/html");
		PrintWriter out = resp.getWriter();
		String name = req.getParameter("name");
		out.println("<h1> hello " + name + "</h1>");
		out.close();
	}

//	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//		 System.out.println("service 생성");
//	}

 

링크를 클릭하는 것은 GET 방식으로 서버에게 요청을 보내는 것입니다.

그럼 service() 메소드는 자신의 doGet() 메소드를 실행합니다.

 

<form> 의 method를 post로 설정하였기에 doPost()가 실행되었습니다.

input의 name 매개변수 속 내용을 읽어오기 위해 req.getParameter("name"); 을 사용했습니다.

 

같은 url이지만 post 또는 get 방식에 따라 다른 내용이 출력되게 한 것입니다.

 

 

 

 

+) Run on Server 실패 시

Run on server하려는데 8005, 8080 포트를 종료하거나 포트 번호 바꾸라고 해서 종료부터 해보았다.

두 포트가 같은 PID를 가지고 있어서 종료하면 톰캣 자체도 그대로 끝나서 서버를 열 수 없었다.

그래서 톰캣을 다시 열었는데 그럼 또 두 포트 모두 다 열려있어서 에러 뜬다.

그래서 포트 번호를 바꾸기로 했다.

 

하단 창에서 Server의 톰캣을 더블클릭하여

각 포트 번호를 다 바꿔준 뒤 실행하니 문제 없었다.

728x90
반응형

'Web > Java+Spring' 카테고리의 다른 글

JSP  (0) 2021.05.08
Request, Response  (0) 2021.05.06
Servlet  (0) 2021.05.05
JAVA 웹 어플리케이션 (HttpServlet) 컴파일 및 실행  (0) 2021.05.05
Apache Tomcat WAS 설치  (0) 2021.05.05