Backend/Servlet

서블릿 프로젝트 생성 및 매핑 방법 : web.xml / annotation

olli2 2021. 12. 27. 10:47

서블릿 프로젝트 생성 

  • 새 프로젝트 :  Dynamic Web Project
  • 프로젝트명 : Servlet01
  • Next 눌러 Generate web.xml 체크 필수

<Classpath에 servlet-api.jar 추가하기>

  • 프로젝트 우클릭 -> Properties
  • Java Build Path / Libraries 탭 / Classpath에서 [Add External JARs..]
  • apache-tomcat-9.xxx\lib에서 servlet-api.jar 파일 선택
  • [Apply and Close]

<패키지 생성>

  • src/main/java 폴더에 패키지 sec01 생성

<위에서 생성한 패키지 안에 서블릿 클래스 FirstServlet 생성 (New - Servlet)>

  • FirstServlet
  • init() / destroy() / doGet() 메소드 선택 
  • doGet() : 디폴트

서블릿 프로젝트 생성 예제 및 실행 결과

package sec01;

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;

/**
 * Servlet implementation class FirstServlet
 */
@WebServlet("/FirstServlet")
public class FirstServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see Servlet#init(ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		System.out.println("init 메소드 호출");
	}

	/**
	 * @see Servlet#destroy()
	 */
	public void destroy() {
		System.out.println("destory 메소드 호출");
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
		System.out.println("doGet 메소드 호출");
	}

}

 

실행 결과

    • 웹 브라우저 : http://localhost:8080/Servlet01/FirstServlet  요청
    • 디폴트로 doGet() 메소드 호출 (doPost() 있어도 호출 안 됨)
    • 콘솔창 출력 확인
      • init 메소드 호출 (최초 1번 실행)
      • doGet 메소드 호출
    • 웹 브라우저에서 새로고침
      • ‘doGet 메소드 호출’ 만 호출
      • init 메소드는 처음 한 번 만 호출되고, 이후 doGet() / doPost() 호출
    • 변경사항 발생시킨 후 저장 -> destory() 호출

서블릿 매핑 방법

[1] web.xml에서 설정

아래 코드를 <web-app> 태그 내부에 삽입

<servlet>
  <servlet-name>myFirst</servlet-name>
  <servlet-class>sec01.FirstServlet</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>myFirst</servlet-name>
  <url-pattern>/first</url-pattern>
</servlet-mapping>

web.xml 변경 시, 톰캣 서버 중단 후 재시작 필수

결과 : http://localhost:8080/Servlet01/first

 

요청 처리 객체 / 응답 처리 객체 

  • HttpServletRequest request와 HttpServletResponse response
  • 톰캣에서 request 객체와 response 객체 생성해서 doGet() 메소드 안에 인자 값으로 넣어줌
  • request 객체 (요청 처리 객체) : 클라이언트에서 입력한 데이터가  request 객체에 담겨져서 서버로 전달
  • response 객체 (응답 처리 객체) : 서버 측에서 처리한 결과를 response 객체에 담아서 클라이언트로 전달
  • doGet()과 doPost() 둘 다 매개변수로 request/ response 객체를 가짐 (클라이언트 요청 처리, 클라이언트에게 응답 처리)

서블릿 동작 과정

  • http://localhost:8080/Servlet01/first 로 요청 들어옴
  • FirstServlet이 메모리에 존재하는지 체크 -> 없으면 FirstServlet을 메모리에 로드
  • init() 메소드 호출
  • doGet() 또는  doPost() 메소드 호출
  • 클라이언트에게 결과 응답
  • 클라이언트2의 경우) FirstServlet이 메모리에 존재하는지 체크 -> 클라이언트1의 요청에 의해 로드된 내용 존재하기 때문에 로드 과정 생략됨 -> 빠른 속도

 

doGet() 디폴트 확인 예제 : ThirdServlet.java

  • doGet() 없이 doPost() 추가
  • 실행 시 get 방식에서 지원되지 않는 메소드라며 오류 발생

package sec01;

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;

/**
 * Servlet implementation class ThirdSServlet
 */
@WebServlet("/ThirdServlet")
public class ThirdServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see Servlet#init(ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		System.out.println("init 메소드 호출3");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doPost 메소드 호출");
	}
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doGet 메소드 호출");
	}
}

 

doGet()과 doPost() 둘 다 처리할 수 있는 방식 사용 예제

  • doHandle() 또는 doProcess() 메소드 추가
  • doGet()과 doPost()에서 호출하면서 request, response 객체 전달
  • doHandle()이 모두 처리 
package sec01;

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;

/**
 * Servlet implementation class ThirdSServlet
 */
@WebServlet("/ThirdServlet")
public class ThirdServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see Servlet#init(ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		System.out.println("init 메소드 호출3");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}
	
	protected void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("doHandle 메소드 호출");
	}

}

 

[2] Annotation 이용

  • 어노테이션(Annotation)을 이용한 서블릿 매핑
  • web.xml에서 여러 서블릿 매핑 설정 시 복잡
  • 서블릿 클래스에서 직접 어노테이션으로 서블릿명을 설정 -> 가독성 좋고 편리 / 쉬움
  • 어노테이션이 적용되는 클래스는 반드시 HttpServlet 클래스를 상속받아야 함
  • @WebServlet을 이용해서 서블릿 매핑 구현
@WebServlet("서블릿 매핑 이름")
@WebServlet("/FirstServlet")

 

 

예제 : AnnotationServlet.java

  • 프로젝트 생성 시 지정하거나
  • 클래스에서 @WebServlet() 직접 변경
package sec01;

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;

/**
 * Servlet implementation class AnnotationServlet
 */
@WebServlet("/annot") // 서블릿 매핑 이름 : '/annotServlet' -> '/annot'로 직접 변경
public class AnnotationServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see Servlet#init(ServletConfig)
	 */
	public void init(ServletConfig config) throws ServletException {
		System.out.println("init 메소드 호출 annot");
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doHandle(request, response);
	}
	
	protected void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("annot 메소드 호출");
	}

}