본문 바로가기
Road to Developer/edwith풀스택웹개발자

10. 서블릿 생명주기 (Servlet Life Cycle)와 request, response

by 구월에작은섬 2018. 6. 25.

서블릿을 생성하고 init, service,destroy메서드를 자동생성한다. 

아래처럼 코드를 수정해본다.

package exam;

import java.io.IOException;
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;

@WebServlet("/LifeCycleServlet")
public class LifeCycleServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       public LifeCycleServlet() {
        System.out.println("LifeCycleServelt 생성");
       
    }
	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호출");
	}

}

결과


아직 destroy는 호출되지 않은 모습이다.


한번 더 파일을 새로고침 하거나 실행하면 서블릿을 여러번 실행하는 것이 아니라 WAS는 메모리를 체크해서  Service 메서드만 호출한다.

만약 서블릿이 수정되면, destroy메서드가 호출되고 새롭게 서블릿을 생성하고 init, service가 호출된다.

저번에 doGet()메서드를 사용할 때에는 init, service 메서드를 생성하지 않았는데 어떻게 실행이 된 것일까?

그것은 doGet()메서드가 httpServlet을 상속했기 때문이다.

그러면 doGet() / doPost()메서드를 상속해 보자.


package exam;

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;

@WebServlet("/LifeCycleServlet")
public class LifeCycleServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       public LifeCycleServlet() {
        System.out.println("LifeCycleServelt 생성");
       
    }
	public void init(ServletConfig config) throws ServletException {
		System.out.println("init 호출");
	}
	public void destroy() {
		System.out.println("destroy호출");
	}
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.println("<html>");
		out.println("<title>form</title>");
		out.println("<body>");
		out.println("<form method="post" action="/exam31/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 request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		String name = request.getParameter("name");
		out.println("<h1> hello " + name + "</h1>");
		out.close();
	}
}

doGet메서드로 HTML형식의 페이지를 만들었고, form태그의 post 속성을 이용해서  옆의 페이지 주소로 text타입의 name이라는 값을 submit버튼이 눌리면 전달한다.

doPost메서드로 String변수에 name값을 받아서 /exam31/LifeCycleServlet 페이지에서 html구문을 실행한다.


결과

WAS는 웹 브라우저로부터 Servlet요청을 받으면,

요청할 때가지고 있는 정보를 HttpServletRequest객체를 생성하여 저장합니다.

웹 브라우저에게 응답을 보낼 때 사용하기 위하여 HttpServletResponse객체를 생성합니다.

생성된 HttpServletRequest, HttpServletResponse 객체를 서블릿에게 전달합니다.


HttpServletRequest


http프로토콜의 request정보를 서블릿에게 전달하기 위한 목적으로 사용합니다.

헤더정보, 파라미터, 쿠키, URI, URL 등의 정보를 읽어 들이는 메소드를 가지고 있습니다.

Body의 Stream을 읽어 들이는 메소드를 가지고 있습니다.


HttpServletResponse


WAS는 어떤 클라이언트가 요청을 보냈는지 알고 있고, 해당 클라이언트에게 응답을 보내기 위한 HttpServleResponse객체를 생성하여 서블릿에게 전달합니다.

서블릿은 해당 객체를 이용하여 content type, 응답코드, 응답 메시지등을 전송합니다.

예제를 통해 학습해 보자.


1. 헤더정보

HeaderServlet클래스를 생성하고 URLMapping을 /header로 해 주었다.

자동생성된 doGet()메서드의 내용을 아래처럼 변경해 주었다.

package exam;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

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

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

	public HeaderServlet() {
		super();

	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.println("");
		out.println("<title>form</title>");
		out.println("<");

		Enumeration<string> headerNames = request.getHeaderNames();
		while (headerNames.hasMoreElements()) {
			String headerName = headerNames.nextElement();
			String headerValue = request.getHeader(headerName);
			out.println(headerName + " : " + headerValue + " <br /> ");
		}

		out.println("");
		out.println("");
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doGet(request, response);
	}

}

request.getHeaderNames()를 통해 Enumeration 객체를 반환한다.

헤더의 이름과, 값을 아래 코드를 이용해 알아낼 수 있다.

결과


: (콜론)을 기준으로 헤더이름과 헤더 값을 나타낸다.


2. 파라미터 읽어들이기
PrameterServlet클래스를 생성한다.
아래처럼 코드를 수정한다.
package exam;

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;

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

	public ParameterServlet() {
		super();

	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.println("<html>");
		out.println("<title>info</title>");
		out.println("<body>");

		String uri = request.getRequestURI();
		StringBuffer url = request.getRequestURL();
		String contentPath = request.getContextPath();
		String remoteAddr = request.getRemoteAddr();
		String name = request.getParameter("name");
		String age = request.getParameter("age");
		
		out.println("name : " + name + "<br />");
		out.println("age : " +age + "<br />");
		out.println("<br />");
		out.println("uri : " + uri + "<br />");
		out.println("url : " + url + "<br />");
		out.println("contentPath : " + contentPath + "<br />");
		out.println("remoteAddr : " + remoteAddr + "<br />");
		
		out.println("<body>");
		out.println("<html>");

	}

}
아래 사진 URL주소에 ?name=henry&age=20이 보이는가?
저런 형태로 URL을 통한 파라미터 전달이 가능하고, form태그의 input속성을 이용할 수도 있다.
결과


자료 출처 : http://www.edwith.org/boostcourse-web/lecture/16688/


반응형