csmoon1010의 SW 블로그

Servlet _ 작성 방법 / 라이프 싸이클 / Request, Response 객체 (부스트코스) 본문

웹/백엔드

Servlet _ 작성 방법 / 라이프 싸이클 / Request, Response 객체 (부스트코스)

csmoon1010 2021. 1. 29. 19:48

1. Java Web Application(자바 웹 어플리케이션)

: WAS에 설치(deploy)되어 동작하는 어플리케이션

 

1) 구성 요소

- HTML, CSS

- 이미지

- 자바 클래스(Servlet, package, interface 등)

- 각종 설정 파일 등

 

 

2) 폴더 구조

(1) WEB-INF 폴더

- web.xml 파일

  • 배포기술자
  • 웹 애플리케이션에 대한 정보를 다 가지고 있음
  • Servlet  3.0미만에서는 필수, 그 이상 부터는 어노테이션으로 대체 가능

- lib 폴더 (라이브러리) : 각종 자료 파일들

- classes : 클래스들(java 패키지, class 들)

 

(2) 리소스들 : 각종 폴더, 이미지, 다양한 리소스

 

 

2. Servlet

: 자바 웹 어플리케이션의 구성요소 중 동적인 처리를 하는 프로그램의 역할

- WAS에서 동작하는 Java 클래스

- HttpServlet 클래스를 상속받음

 

⇨ 서블릿과 JSP를 조화롭게 사용해야 최상의 결과를 가진 웹 페이지를 개발할 수 있음

(ex> 웹 페이지 구성 화면 - JSP / 복잡한 프로그래밍 - 서블릿)

 

※ 단, 실제 웹 개발 시에는 서블릿을 직접 쓰지는 않는다. Spring과 같은 프레임워크를 사용해 더 편하게 개발하는 중

 

 

 

1) ver 3.0 spec 이상에서의 작성

 

- web.xml 파일 대신 자바 annotation을 사용해 작성이 간결해짐

- 동적인 처리 : 지정한 url을 통해 요청이 들어왔을 때 서블릿이 실행 → 응답할 코드 생성 & 응답

 

 

(1) 초기 Dynamic Web Project 생성

- output folder - build\classes : 서블릿이 컴파일되면 컴파일된 클래스 파일은 이 디렉토리 안으로 들어감

- web.xml : 3.xx 이상 ver에서는 어노테이션을 이용하기 때문에 web.xml이 필수X

   ※ 단, Spring 사용시 다른 설정 부분을 web.xml에 추가해야 하므로 사용하기도 함

 

 

(2) 서블릿 예시 : 1-10까지 출력

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("/ten")
public class TenServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

    public TenServlet() {
        super();
    }
    
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<h1>1-10까지 출력!!</h1>");
        for(int i = 1; i <= 10; i++) {
            out.println(i + "<br>");
        }
        out.close();
    }
}

- [Annotation] @WebServlet("/ten") : URL mapping 값 변경 가능

- HttpServletRequest, HttpServletResponse : 요청/응답에 대한 정보들을 추상화시킨 객체

- response.setContentType("text/html; charset=utf-8");

  • 응답한 정보의 type : text/html
  • 응답한 정보의 인코딩(charset) : utf-8

- response.getWriter() : 응답 내용을 담을 수 있는 PrintWriter 객체를 제공

 

 

 

 

2) ver 3.0 spec 미만에서의 작성

 

- Servlet을 등록 시 web.xml파일에 직접 등록

 

 

 

(1) 서블릿 예시 : 1-10까지 출력

 

web.xml

Annotation 대신 web.xml에 클라이언트가 요청했을 때 실행할 서블릿 등록

- <servlet> : 똑같은 이름의 servlet-name이 있는지 check

- <servlet-mapping> : 어떤 url(<url-pattern>)로 요청하면 <servlet-name>이 같은 서블릿을 찾음

(만일 찾지 못하면 404 message를 보여줌)

- <servlet-class> : 실제로 실행시킬 서블릿 확인 (package명.서블릿클래스명)

- <url-pattern> : URL mapping 값 설정

 

package exam;

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

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


public class TenServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

    public TenServlet() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("<h1>1-10까지 출력!!</h1>");
        for(int i = 1; i <= 10; i++) {
            out.println(i + "<br>");
        }
        out.close();
    }
}

 

 

 

 

3) Servlet 라이프 사이클(Servlet Life Cycle)

메소스들이 언제 생성되고 호출되는가?

 

package examples;

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("LifeCycleServlet 생성"); //콘솔에 출력
    }

	public void init(ServletConfig config) throws ServletException {
		System.out.println("init test 호출");
	}

	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();
	}

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

 

(1) init()

메모리에 없다면 생성자를 통해 객체 생성 후 init()메소드 실행

 

(2) service(request, response)

요청이 들어왔을 때 응답해야 되는 모든 내용을 담고 있음. 즉, 요청이 들어올 때마다 호출

- HttpServlet의 service 메소드는 "템플릿 메소드 패턴"으로 구현됨

 

cf> 템플릿 메소드 패턴 : 전체적인 레이아웃을 통일 시키지만 상속받은 클래스로 하여금 어느정도 유연성을 주도록하는 디자인 패턴

- 추상 메소드와 훅 메소드를 적절히 사용

- 훅 메소드 : abstract 키워드를 붙이지 않아 무조건적으로 구현하지 않아도 되는 메소드

jdm.kr/blog/116

 

 

- 클라이언트 요청 (URL에서 직접) : GET --> doGet(request, response) 호출

- 클라이언트 요청 (입력과 함께) : POST --> doPost(request, response) 호출

   

   ex> <form>을 통해 name을 입력받고 post방식으로 서블릿 요청

       → req 객체로부터 name으로 지정된 값을 꺼내서 출력해줄 수 있음

  즉, 클라이언트가 요청 시 넣어준 값에 따라 동적으로 웹 페이지를 변경함

 

 

(3) destroy()

- WAS가 종료된 경우

- 웹 애플리케이션이 새롭게 갱신(Servlet의 변경)되는 경우

 

====================== 정리 ======================

메소드 호출 순서

  • WAS는 서블릿 요청을 받으면 해당 서블릿이 메모리에 있는지 확인합니다.
    •  if (메모리에 없음) {
       - 해당 서블릿 클래스를 메모리에 올림
       - init() 메소드를 실행
      }
       - service()메소드를 실행
  • was가 종료되거나, 웹 어플리케이션이 새롭게 갱신될 경우 destroy() 메소드가 실행됩니다.

 

 

 

 

 

 

 

www.boostcourse.org/web316/lecture/16686

 

웹 프로그래밍(풀스택)

부스트코스 무료 강의

www.boostcourse.org

 

Comments