Servlet은 주로 웹서버에서 동작하는 애플리케이션을 구현할 때 사용
외부 프로그램을 호출하고 수행결과를 웹 브라우저로 전송하는 CGI의 동시 처리 단점을 보완하기 위해 나온 기술
웹 애플리케이션 |
웹 애플리케이션 접근
- Servlet은 웹서버에서 서비스 되는 페이지(Servlet이 웹서버에 존재해야 함)
웹서버가 클라이언트에 서비스하는 단위는 웹 애플리케이션.
웹 애플리케이션 위치
- 서비스는 서버에서 애플리케이션 단위로 이루어 짐
- 웹 서버마다 시작될 때 자동으로 애플리케이션으로 인식하여 서비스를 올려주는 디렉터리가 있음
- 톰캣은 webapps 디렉터리에 있는 하위 디렉터리 또는 디렉터리가 압축된 war 파일은 하나의 애플리케이션으로 인식
웹 애플리케이션 구조
- 웹 애플리케이션은 하나의 디렉터리
- 필수 웹 애플리케이션 파일: WEB-INF 디렉터리, web.xml
- WEB-INF/classes 디렉터리, WEB-INF/lib
환경설정 파일: web.xml
- 웹서버는 각 웹 애플리케이션의 web.xml을 읽음
- 웹 애플리케이션 실행에 관해 정의하는 환경설정 파일
서블릿 디렉터리
- 서블릿 디렉터리란, 서블릿이 공식적으로 존재하는 디렉토리(서블릿 컨테이너를 내장한) 모든 WAS의 구조
- 서블릿 프로그램 실행에 관련된 클래스 파일들은 해당 디렉터리에 있어야만 서블릿 컨테이너가 인식하여 실행 가능
- WEB-INF/classes
- 서블릿을 개발할 때는 소스 폴더에 자바 소스를 작성하면 장동으로 컴파일 되어 클래스 파일이 생성
Servlet 구현 |
웹 브라우저에서 클라이언트의 요청에 따라 서버가 실행할 수 있는 자바 프로그램은 서블릿 뿐
서블릿 API를 상속하면 웹에서 동작하는 기본 조건을 갖출 수 있음
서블릿 API 문서
서블릿을 구현할 때 WAS에서 제공하는 서블릿 APIㄹ를 상속받거나 필요한 메서드를 재정의해야 함.
- 톰캣에서 제공하는 서블릿 API문서
[Document] -> Tomcat X.0 -> [Reference] -> Servlet X.0 Specification and Javadoc 클릭
https://tomcat.apache.org/
서블릿 클래스 간의 관계
서블릿을 구현할 때 반드시 HttpServlet 클래스를 상속받아야 함
HttpServlet에는 웹상에서 클라이언트 요청이 있을 때 해당 서블릿을 실행하는 모든 조건이 포함되어 있음
서블릿 프로그램의 클래스 계층 구조
https://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServlet.html
- Servlet 인터페이스
서블릿 프로그램을 개발할 때 반드시 구현해야 하는 메소드를 선언하고 있는 인터페이스
ex) init(), destroy(), getServletConfig(), getServletInfo() 등 - GenericServlet 클래스
Servlet 인터페이스를 상속하여 클라이언트-서버 환경에서 서버단의 애플리케이션으로 필요한 기능을 구현한 추상 클래스
service() 메소드를 제외한 모든 메소드를 재정의 함
GenericServlet 클래스를 상속하면 애플리케이션의 프로토콜에 따라 메소드 재정의 구문 적용 필요 - HttpServlet 클래스
GenericServlet 클래스를 상속하여 service() 메소드를 재정의함으로써 HTTP 프로토콜에 알맞은 동작을 수행하도록 구현한 클래스
HTTP 프로토콜 기반으로 브라우저로부터 요청을 전달받아서 처리하도록 하는 클래스
service() 메소드에는 요청방식(GET 또는 POST)에 따라 doGet(), doPost() 등 정해진 사양의 메소드가 호출 되도록 구현
반드시 구현해야 하는 메소드는 없음
서블릿 작성
import javax.servlet.http.HttpServlet;
public class FirstServlet extends HttpServlet{
}
- import javax.servlet.http.*;
서블릿을 작성하기 위해 상속받아야 하는 HttpServlet 클래스가 있는 패키지를 포함하는 소스 - public class FirstServlet extends HttpServlet{}
웹상에서 HTTP 프로토콜을 이용해 서비스를 처리하기 위해 반드시 HttpServlet을 상속 받아야 함.
서블릿 실행 순서
java SE 프로그램은 개발자가 프로그램 실행 순서를 제어하는 것과 달리 Java EE 기반 프로그램은 실행의 흐름을 컨테이너가 제어함.
제3자가 프로그램의 실행 흐름을 제어하는 것을 IoC(Inversion of Control) 제어의 역전 이라고 함.
- 클라이언트로부터 처리 요청 받음
클라이언트가 요청을 보내면 웹서버에서 이를 받아서 요청정보의 헤더안의 URI 분석
요청 받은 페이지가 서블릿이면 서블릿 컨테이너에 처리를 넘김
요청 받은 서블릿을 WEB-INF/classes나 WEB-INF/lib에서 찾아서 실행 - 최초의 요청 여부 판단
서블릿 컨테이너는 서블릿이 최초 요청인지 판단
실행할 서블릿 객체가 메모리에 없으면 최초 요청, 이미 있으면 최초 요청이 아닌 것으로 판단.
최초의 요청은 처음 요청할 때 딱 한 번만 실행된다. - 서블릿 객체 생성
서블릿 컨테이너는 최초의 요청이면 서블릿을 메모리에 로딩하고 객체를 생성
이때 생성된 객체를 계속 사용 - init() 메소드 실행
init()는 서블릿 객체가 생성된 다음 호출되는 메소드로서, Servlet 인터페이스에 선언되어 있고, 기능은 GenericServlet 클래스에 구현되어 있음.
주로 서블릿 객체의 초기화 작업이 구현되어 있음. - service() 메소드 실행
service() 메소드는 실행하는 서블릿 요청 순서에 상관없이 요청이 있을 때마다 실행
실제 서블릿에서 처리해야 하는 내용이 구현되어 있음
Servlet 인터페이스에 선언되어 있고, GenericServlet 클래스에 abstract 메소드로 선언 되어 있으므로 HttpServlet 클래스에 메소드 몸체가 구현되어 있음
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class FirstServlet extends HttpServlet{
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("init() 실행됨!");
}
@Override
public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
System.out.println("service() 실행됨!");
}
}
콜백 메소드와 서블릿 객체의 생명주기
콜백 메소드란, 어떤 객체에서 어떤 상황이 발생하면 컨테이너가 자동으로 호출하여 실행되는 메소드, 이러한 메소드들이 서블릿을 실행 함
init(), service() , destroy()같은 메소드들이 서블릿 객체에 이벤트가 발생하면 호출 됨.
init(): 클라이언트로부터 최초로 서블릿 요청이 있을 때 한번 실행되는 초기화 메소드
service(): 클라이언트로부터 요청이 있을 때마다 n번 실행되는 실제 서블릿이 처리 로직 메서드
destroy(): 서블릿 객체가 메모리에서 삭제될 때(서비스나 서버 중지) 1번 자원 해제하는 메소드
- 서블릿 객체의 생성
서버 입장에서 클라이언트로부터 최초로 서블릿 실행 요청이 있을 때 서블릿 객체가 생성 됨.
서블릿 요청이 최초인지 판단하는 기준은 객체 생성 여부로 판단
하나의 객체로 재사용하기 때문에 처리속도, 메모리 부분에서 장점
- 최초 요청 시: init() -> service()
- 이후 요청 시: service()
- 서블릿 객체의 삭제
서블릿 객체가 삭제되는 시점은 서버에서 웹 애플리케이션 서비스가 중지되는 시점
이때 destroy 메소드가 호출 됨
Servlet 실행 |
WEB-INF 디렉터리에 있는 web.xml 파일은 웹 애플리케이션에 관한 환경설정 파일로서 웹서버가 시작할 때 web.xml 파일에 설정된 내용대로 서비스를 올려 줌
/WEB-INF/classes,/ WEB-INF/lib 디렉터리에 있는 파일들도 애플리케이션 서버가 사용.
/WEB-INF는 서버가 사용하는 파일이 들어 있는 중요한 디렉터리이므로 외부에서 클라이언트가 곧바로 접근할 수 없도록 막아 놓음
web.xml
클라이언트가 Servlet에 접근할 수 있게 설정해주는 파일
- 설정방법
1. WEB-INF/web.xml 파일을 클릭
2. <welcome-file-list> </welcome-file-list> 테그 사이의 소스를 지우고 아래와 같이 설정
<servlet>
<servlet-name>first</servlet-name>
<servlet-class>test.FirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>first</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
- 태그 설명
1. <servlet>
HttpSerlvet을 상속받고 있는 클래스를 web.xml에 등록할 때 사용
반드시 하위에 <servlet-name>과 <servlet-class> 태그를 가져야 함
2. <servlet-name>
등록하는 서블릿의 이름을 부여함
실제 존재하는 이름이 아닌 지정한 이름이며 지정한 이후에는 클래스 이름을 사용하면 안됨
3. <servlet-class>
등록하는 서블릿의 실제 클래스 이름 지정
웹 서버가 찾아갈 때 사용하는 정보로 패키지명과 함께 지정해 줘야 함
4. <servlet-mapping>
web.xml에서 <servlet> 태그로 등록한 서블릿을 실행 요청할 때 사용할 URI를 지정하기 위해 사용
<servlet>태그를 사용했을 때만 부가적으로 사용
5. <servlet-name>
실행할 서블릿 이름을 지정 함
<servlet> 태그에서 등록한 서블릿 이름으로 지정해야 함
6. <url-pattern>
서블릿을 실행할 때 사용할 URL을 지정 함
URL을 지정할 때 전체 URL을 모두 지정하는 것은 아니고 http://서버주소:포트번호/웹 애플리케이션이름 까지는 생략
@WebServlet을 통해 접근
애노테이션: 컴파일러에 정보를 알려주거나 자바프로그램 실행에 관한 내용을 설정하는 용도
서블릿의 클래스 선언부 앞에 @WebServlet(접근 시 사용할 URI)를 지정하면 됩니다.
web.xml에 지정 되어 있는 것과 중복되므로 web.xml 주석처리
- @WebServlet 어노테이션 속성
description: 서블릿 설명 입력
displayNames: 외부에 표시되는 서블릿 이름
initParams: @WebInitParam 어노테이션들 추가
largelcon 서블릿에서 사용하는 큰 크기 아이콘 위치
loadOnStartup 서블릿이 컨테이너에 로드 되는 순서 지정
name 서블릿 이름
smalllcon 서블릿에서 사용하는 작은 크기 아이콘 위치
urlPatterns 해당 서블릿을 호출할 URL 패턴
value urlPatterns와 같은 용도, 속성 이름 생략 가능
요청방식에 따른 실행
HttpServlet 클래스에 구현된 service() 메소드를 재정의하여 메소드의 몸체를 구현해야 하지만 HttpServlet에서 구현된 service9)메소드를 그대로 실행하고 싶을 때는 재정의 하지 않음
- HttpServlet은 두가지 형태의 service()를 가지고 있음
1. protected void service(HttpServletRequest req, HttpServletResponse resp)
클라이언트의 실행요청에 따라 서로 다른 메소드를 호출하도록 구현
2. public void service(ServletRequest req, ServletResponse resp)
서블릿 요청이 있을 때마다 실행되는 메소드
같은 객체 있는 protected void service를 호출만 함
- 요청정보 구성
1. 요청방식
GET, POST, PUT, DELETE 등이 존재
service() 메소드는 이 요청방식 정보를 추출한 후 추출된 요청방식 정보에 따라 서로 다른 메소드를 호출하도록 구현 - HttpServlet에 선언된 메소드
1. doDelete(HttpServletRequest req, HttpServletResponse resp)
2. doGet(HttpServletRequest req, HttpServletResponse resp)
3. doHead(HttpServletRequest req, HttpServletResponse resp)
4. doOptions(HttpServletRequest req, HttpServletResponse resp)
5. doPost(HttpServletRequest req, HttpServletResponse resp)
6. doPut(HttpServletRequest req, HttpServletResponse res)
7. doTrace(HttpServletRequest req, HttpServletResponse resp)
똑같은 URI 요청을 요청방식에 따라 다르게 하려면 service() 메소드를 제정의 하지 말고 doGet() 또는 doPost() 등을 재정의하여 사용
import java.io.IOException;
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("/second") //서블릿 실행을 위한 URI를 "/second"로 설정
public class SecondServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
System.out.println("SecondServlet");
}
}
//1) init(servletConfig) - GenericServlet 실행
//2) service(ServletRequest, ServletResponse) - HttpServlet 실행
//3) service(HttpServletRequest, HttpServletResponse) - HttpServlet 실행
//4) doGet(HttpServletRequest, HttpServletResponse) -SecondServlet 실행
'프로그래밍 > Servlet & JSP' 카테고리의 다른 글
[Servlet & JSP] 자바와 웹 (0) | 2022.12.15 |
---|