[Java] 서블릿 이해하기
by Choi HyeSun
서블릿(Servlet)이란?
배우는 이유
-
정적 웹 페이지의 문제점을 보완하여 나온 것이 동적 웹페이지를 구현하는 것
- 초기 동적 웹 페이지를 서블릿(Servlet, 자바로 만든 CGI 프로그램)을 이용해서 구현
-
서블릿의 문제점을 보완하여 나온것이 JSP
- JSP의 많은 기능은 Servlet을 따름
-
Servlet을 먼저 이해하고 나면 JSP를 조금 더 쉽게 이해할 수 있음
- 실제로 웹 애플리케이션 개발시 JSP와 서블릿이 각자의 고유한
서블릿이란?
-
서버 쪽에서 실행되면서 클라이언트의 요청에 따라 동적으로 서비스를 제공하는 자바 클래스
-
자바로 작성되어 있으므로 자바의 일반적인 특징을 모두 가짐
-
일반 자바 프로그램과 다르게 독자적으로 실행되지 못하고 톰캣과 같은 JSP/Servlet 컨테이너에서 실행되는 차이가 있음
- JSP/Servlet 컨테이너는 톰캣 뿐만 아니라 JEUS, Web Logic, JBOSS, 기업에서 제작하는 유료 컨테이너 등이 있음
-
서버에서 실행되다가 웹브라우저에서 요청을 하면 해당 기능을 수행한 후 웹 브라우저에 결과를 전송
-
서버에서 실행되므로 보안과 관련된 기능도 훨씬 안전하게 수행 가능
서블릿 동작 과정
-
Client → Web Server 요청
-
Web Server → Was Server 위임
-
Was Server → Servlet 호출
-
Servlet 실행 (요청에 대한 기능들 수행)
-
Servlet → Was Server 결과 반환
-
Was Server → Web Server 결과 반환
-
Web Server → 클라이언트 결과 반환
서블릿의 기능
-
단순히 고정된 정보를 브라우저에 보여주는 것 → 웹 서버
-
쇼핑몰 화면에 실시간으로 변하는 상품의 할인 가격을 보여주려면 상품의 할인 가격을 데이터 베이스에서 가져오는 기능이나 직접 계산하는 기능이 필요
-
이런 기능을 서버쪽에서 서블릿이 처리
-
상품 할인 가격 표시처럼 웹 페이지에서 동적으로 변하는 정보를 효과적으로 다룰 수 있음
-
그 외 서블릿 특징
-
서버 쪽에서 실행되면서 기능을 수행함
-
기존의 정적인 웹 프로그램의 문제점을 보완하여 동적인 여러가지 기능을 제공
-
스레드 방식으로 실행
-
자바로 만들어져 자바의 특징(객체지향)을 지님
-
컨테이너에서 실행
-
컨테이너 종류에 상관 없이 실행(플랫폼 독립적)
-
보안 기능 적용 용이
-
웹 브라우저에서 요청시 기능을 수행
서블릿 API 계층 구조와 기능
서블릿의 계층 구조
-
서블릿은 자바로 만들어졌으므로 클래스들 간의 계층 구조를 가짐
-
서블릿 API 계층 구조
-
Servlet과 ServletConfig 인터페이스를 구현해 제공
-
GenericServlet 추상클래스가 위 두 인터페이스의 추상 메서드를 구현
-
HttpServlet이 GenericServlet을 상속받음
-
서블릿 API 기능
- 서블릿 API를 구현하는 여러 구성 요소들의 특징
서블릿 구성 요소 | 기능 |
---|---|
Servlet 인터페이스 | - javax.servlet 패키지에 선언 - Servlet 관련 추상 메서드를 선언 - init(), service(), getServletInfo(), getServletConfig()를 선언 |
ServletConfig 인터페이스 | - javax.servlet 패키지에 선언 - Servlet 기능 관련 추상 메서드가 선언 - getInitParameter(), getInitParameterNames(), getServletContext(), getServletName()이 선언 |
GenericServlet (추상)클래스 | - javax.servlet 패키지에 선언 - 상위 두 인터페이스를 구현하여 일반적인 서블릿 기능을 구현한 클래스 - GenericServlet을 상속받아 구현한 사용자 서블릿은 프로토콜에 따라 각각 Service()를 오버라이딩해서 구현 |
HttpServlet 클래스 | - javax.servlet.http 패키지에 선언 - GenericServlet을 상속받아 HTTP 프로토콜을 사용하는 웹 브라우저에서 서블릿 기능을 수행 - 웹 브라우저 기반 서비스를 제공하는 서블릿을 만들 때 상속받아 사용 - 요청시 service()가 호출되면서 요청 방식에 따라 doGet()이나 doPost()가 차례대로 호출됨 |
-
GenericServlet
- 일반적인 여러 통신 프로토콜에 대한 클라이언트/서버 프로그램에서 서블릿 기능을 구현할 수 있는 클래스
-
HttpServlet
-
GenericServlet을 상속
-
HTTP 프로토콜을 사용하는 서블릿 기능을 구현하는 클래스
-
HttpServlet을 상속받아 HTTP 프로토콜로 동작하는 웹 브라우저의 요청을 처리하는 서블릿을 만들어 볼 것
-
그 외 다른 서블릿 구성요소들의 기능은 API 문서를 참고
-
주요 메서드와 기능
-
메서드 | 기능 |
---|---|
protected doDelete(HttpServletRequest req, HttpServletResponse resp) |
서블릿이 DELETE request를 수행하기 위해 service()를 통해서 호출 |
protected doGet(HttpServletRequest req, HttpServletResponse resp) |
서블릿이 GET request를 수행하기 위해 service()를 통해서 호출 |
protected doHead(HttpServletRequest req, HttpServletResponse resp) |
서블릿이 HEAD request를 수행하기 위해 service()를 통해서 호출 |
protected doPost(HttpServletRequest req, HttpServletResponse resp) |
서블릿이 POST request를 수행하기 위해 service()를 통해서 호출 |
protected service(HttpServletRequest req, HttpServletResponse resp) |
표준 HTTP request를 public service()에서 전달받아 doXXX() 메서드를 호출 |
public service(HttpServletRequest req, HttpServletRequest resp) |
클라이언트의 request를 protected service()에게 전달 |
- 클라이언트 요청시 public service() 메서드를 먼저 호출 후 다시 protected service() 메서드를 호출, 그 다음 request에 따라 doXXX() 메서드를 호출
서블릿의 생명주기 메서드
-
서블릿도 자바 클래스이므로 실행하면 당연히 초기화 과정 메모리에 인스턴스를 생성하여 서비스를 수행 다시 소멸하는 과정을 거침
-
이런 단계를 거칠 때 마다 서블릿 클래스의 메서드가 호출되어 초기화, 데이터베이스 연동, 마무리 작업을 수행
-
각 과정에서 호출되어 기능을 수행하는 메서드 : 서블릿 새생명주기 메서드
-
-
서블릿 생명주기(Life Cycle) 메서드
- 서블릿 실행마다 호출되어 기능을 수행하는 콜백 메서드
-
서블릿의 생명주기 메서드 기능과 특징
- init() 실행 초기에 서블릿 기능 수행과 관련된 기능을 설정하는 용도로 많이 사용, 생략 가능
- destroy() 서블릿이 메모리에서 소멸될 때 여러가지 종료 작업 수행, 생략 가능
- doGet(), doPost() do로 시작하는 메서드는 서블릿의 핵심 기능을 처리하므로 반드시 구현
생명주기 단계 | 호출 메서드 | 특징 |
---|---|---|
초기화 | init() | - 서블릿 요청시 맨 처음 한 번만 호출 - 서블릿 생성시 초기화 작업을 주로 수행 |
작업 수행 | doGet() doPost() |
- 서블릿 요청시 매번 호출 - 실제로 클라이언트가 요청하는 작업을 수행 |
종료 | destroy() | - 서블릿이 기능을 수행하고 메모리에서 소멸될 때 호출 - 서블릿의 마무리 작업을 주로 수행 |
FirstServlet을 이용한 실습 - 사용자 정의 서블릿을 만들어보기
이클립스에서 서블릿을 만들고 실행하는 과정
-
사용자 정의 서블릿 클래스 만들기
-
서블릿 생명주기 메서드 구현
-
서블릿 매핑 작업
-
웹 브라우저에서 서블릿 매핑명으로 요청하기
사용자 정의 서블릿 만들기
-
웹 프로그래밍에서 사용되는 사용자 정의 서블릿
-
HttpServlet 클래스를 상속받아서 만듦
-
3개의 생명주기 메서드를 오버라이딩해서 기능을 구현(init(), doGet, destroy())
-
-
형식
톰캣의 servlet-api.jar 클래스 패스 설정하기
-
서블릿 API들은 톰캣의 servlet-api.jar 라이브러리 제공
- 이클립스의 프로젝트에선 서블릿을 사용할면 반드시 클래스 패스를 설정해야 함
-
설정 방법
-
이클립스 상단의 New > Dynamic Web Project
-
프로젝트명 : pro05, 경로 : D:\git\sunny\pro05 > Next > Next
-
[체크] Generate web.xml deployment descriptor > Finish
-
생성된 프로젝트 pro05를 선택 > 마우스 우클릭 > Build Path > Configure Build Path…
-
Java Build Path 창에서 Libraries 탭 > Add Extends JARs…(우측 2번째 button)
-
\%CATALINA_HOME\% (D:\tomcat9)의 lib 디렉터리의 servlet-api.jar를 선택 후 열기 > Apply and Close
-
첫 번째 서블릿 만들기 (FirstSerlvet.java)
-
pro05프로젝트의 Java Resource 디렉터리 하위의 src 선택 > 마우스 우클릭 > New > Package
-
Name : sec01.ex01 > Finish > 패키지 생성 확인
-
생성된 패키지 선택 > 마우스 우클릭 > New > Class
-
Name : FirstServlet > Finish > 생성됨 확인
-
자바 코드 작성(FirstServlet.java)
-
HttpServlet 상속
-
3개의 생명주기 메서드를 차례로 구현
-
각 메서드는 호출시 메시지만 출력
-
서블릿 매핑하기
-
브라우저에서 서블릿명으로 요청하는 방법
-
톰캣에 프로젝트 추가
-
프로젝트명 뒤 패키지명이 포함된 클래스명 전부를 입력
-
http://IP주소:port/프로젝트명/패키지명포함클래스명
-
http://127.0.0.1:8090/pro05/sec01.ex01.FirstServlet
-
이렇게 되면 입력하기가 불편하고 보안에도 좋지 않음
서블릿 클래스명에 대응되는 서블릿 매핑명으로 실제 서블릿을 요청 (톰캣에 등록은 해야함)
-
-
서블릿 매핑 과정
-
각 프로젝트에 있는 web.xml 설정
-
<servlet>태그와 <servlet-mapping> 태그 이용
-
여러 개의 서블릿 매핑 시 <servlet> 태그를 먼저 정의 후 <servlet-mapping> 태그를 정의
-
-
실제 서블릿 매핑의 예
-
<servlet> <servlet-mapping> 하위 태그에 공통으로 <servlet-name>이 들어감
-
공통으로 들어가는 <servlet-name> 태그의 같은 값(예제에선 aaa)이 <servlet>과 <servlet-mapping> 태그를 연결해 줌
-
웹 브라우저에서 <servlet-mapping>의 <url-pattern> 태그의 URL(예제에선 /first)로 요청
-
<servlet-mapping>의 <url-pattern>에 해당하는 <servlet-name> 값(예제에선 aaa)확인
-
확인한 값(aaa)을 <servlet>의 <servlet-name>에서 찾고 태그를 연결시켜 줌
-
브라우져에서 /
의 /first로 요청할 경우, aaa값을 가지는 \ 태그를 찾아 실제 서블릿인 sec.ex01.FirstServlet을 실행
-
-
서블릿 매핑을 실제 프로젝트에 적용해보기
-
pro05 프로젝트의 WebContent > WEB-INF 폴더 클릭 > web.xml을 엶
-
<web-app> 태그의 하위 태그를 지우고 거기에 서블릿 매핑을 작성
-
톰캣에 프로젝트 실행
-
새로 만든 서버(pro05)를 톰캣에 등록
-
톰캣 재실행
-
웹 브라우저에서 서블릿 매핑 이름인 /first로 요청
- http://127.0.0.1:8090/pro05/first
-
이클립스 콘솔에 메시지 찍히는지 확인
-
init 메서드 호출
-
doGet 메서드 호출
-
FirstServlet을 이용한 실습 - 사용자 정의 서블릿을 만들어보기
다수의 서블릿 매핑하기
-
일반적인 웹 애플리케이션은 각 기능에 대한 서블릿을 따로 만들어서 관리
- 즉 프로젝트에서 여러 개의 서블릿을 만들어 사용
다른 서블릿 SecondServlet.java 추가
-
FirstServlet과 동일한 위치에 서블릿 파일 추가
- 내용
-
web.xml 파일에 매핑
-
주의 할 점) 여러개 매핑시 <servlet> 태그와 <servlet-mapping> 태그를 각각 분리해서(개당 1개씩) 작성해야 함
-
<servlet>태그끼리 <servlet-mapping>태그끼리 위치(뭉쳐놓기)
-
<servlet-name>태그 값은 유니크해야함
-
내용
-
-
web.xml 변경사항 반영은 톰캣 재기동 필요 > 톰캣 재시작(정지 후 시작)
-
브라우저에서 각각 요청
-
http://127.0.0.1:8090/pro05/first
-
http://127.0.0.1:8090/pro05/second
-
서블릿 동작 과정
서블릿 동작 과정
-
① 클라이언트가 http://localhost:8090/proc05/first로 요청 (→ 톰캣)
-
② 톰캣이 web.xml에서 서블릿 확인 → sec01.ex01.FirstServlet.java
-
③ 톰캣은 확인한 서블릿이 메모리에 존재하는지 확인 (존재한다면 ⑥으로 이동)
-
④ FirstServlet을 메모리에 로드
-
⑤ init()을 호출
-
⑥ doGet()또는 doPost()를 호출
-
⑦ 결과를 Client에게 응답
특징
-
동일한 작업의 경우, 서블릿은 메모리에 존재하는 서블릿을 재사용
- 훨씬 빠르고 효율적
-
서블릿은 스레드 방식으로 동작
동일한 작업 테스트
-
http://localhost:8090/proc05/first로 요청을 3번 연속 해보기
-
init(초기화)는 1번 실행, doGet(실행)은 3번 실행을 확인할 수 있음
애너테이션을 이용한 서블릿 매핑
web.xml에 서블릿 매핑 vs 애너테이션에 서블릿 매핑
-
web.xml에 여러 서블릿 설정
-
장점) 한 파일에서 확인 가능
-
단점) 파일이 복잡해짐
-
-
애너테이션(@)에 서블릿 매핑
-
소스코드에 직접 기능을 설정
-
톰캣 7 버전부터 사용 가능함
-
장점) 가독성이 좋음
-
단점) 한 파일에서 확인할 수 없음
-
애너테이션을 이용한 서비스 매핑
-
@WebServlet(“url-pattern”)을 클래스 위에 붙여줌
- 예) @WebServlet(“/third”)
-
해당 애너테이션을 사용하려면 꼭 HttpServlet 클래스를 상속받아야 함
- 클래스 클래스명 extends HttpServlet { }
애너테이션을 이용한 서비스 매핑 실습
-
기존처럼 이클립스에서 서블릿 클래스를 직접 만든 후 자바 코드에 애너테이션을 붙여서 매핑할 수도 있음
-
이클립스에서는 서블릿을 만들면서 애너테이션을 바로 적용할 수 있음 ! !
-
실습
-
pro05 프로젝트의 sec01.ex01 패키지를 선택 > 마우스 우클릭 > New > Servlet
-
클래스명 ThirdServlet > Next
-
하단의 URL mappings: /ThirdServlet 선택 > 우측의 Edit… > 패턴 : /third > OK > Next
-
하단 Which method stubs would you like to create에서
[체크해제] Constructors from superclass
[체크-기본값] Inherited abstract methods
메소드 중 init, destroy, doGet 체크 > Finish
-
-
생성 결과(ThirdServlet.java)
-
private static final long serialVersionUID = 1L;
→ 서비스 직렬화를 위해 이클립스에서 자동으로 생성한 상수 -
자동으로 생성된 주석들은 삭제해도 무관
-
@WebServlet("/third")
확인 가능 -
import도 자동으로 되어있고 HttpServlet 상속도 되어있음
-
-
ThirdServlet.java에 기능 추가
- 메세지 출력 기능 추가
-
서블릿 매핑 설정을 했으므로 톰캣 재시작 (정지 > 시작)
-
웹 브라우저에서 서블릿 매핑명(URL패턴)으로 요청
- http://127.0.0.1:8090/pro05/third
-
콘솔 메시지 확인
애너테이션 서블릿 매핑시 주의점
-
매핑명(URL 패턴)이 이미 사용된(URL 패턴)과 중복되지 않도록 주의해야 함
-
중복되면 톰캣 시작시 에러 메시지 발생하며 서버가 정상적으로 뜨지 못함
-
ThirdServlet을 /first로 매핑명 수정하고 테스트해본 결과
-
Caused by: java.lang.IllegalArgumentException: 이름이 [aaa]과 [sec01.ex01.ThirdServlet]인 두 서블릿들 모두 url-pattern [/first]에 매핑되어 있는데, 이는 허용되지 않습니다.
-
-
매핑이 동일하게 되더라도 이클립스에서 선경고를 띄워주진 않는 것 같음
Subscribe via RSS