1. 서블릿이란?
JSP가 나오기 전 자바로 웹 애플리케이션을 개발할 수 있도록 만든 기술.
서버 단에서 클라이언트의 요청을 받아 처리한 후 응답하는 역할.
-서블릿의 특징-
- 클라이언트의 요청에 대해 동적으로 작동하는 웹 애플리케이션 컴포넌트.
- MVC 모델에서 컨트롤러 역할
- 모든 메서드는 쓰레드로 동작
- javax.servlet.http 패키지의 HttpServlet 클래스를 상속받음
2. 서블릿 컨테이너
서블릿의 수명주기를 관리하고, 요청이 오면 스레드를 생성해 처리 해주고, 클라이언트의 요청을 받아서 응답을 보낼 수 있도록 통신 지원
- 통신 지원 : 클라이언트와 통신하려면 서버는 특정 포트로 소켓을 열고 I/O 스트림을 생성 해주는 과정을 API 제공으로 간단히 해결
- 수명주기 관리 : 서블릿을 인스턴스화한 후 초기화 하고, 요청에 맞는 적절한 메서드를 호출한다. 응답한 후에는 가비지 컬렉션을 통해 객체를 소멸시킨다.
- 멀티스레딩 관리 : 서블릿 요청들은 스레드를 생성해 처리합니다. 즉, 멀티스레드 방식으로 여러 요청을 동시에 처리
- 선언적인 보안 관리 및 JSP 지원 : 서블릿 컨테이너는 보안 기능을 지원한다.
3. 서블릿의 동작 방식
- 클라이언트의 요청을 받는다.
- 분석 후 요청을 처리할 서블릿을 찾는다.
- 비즈니스 서비스 로직을 호출한다.
- model 로부터 그 결과 값을 받는다
- request 나 session 영역에 저장한 후 결과 값을 출력할 view를 선택한다.
- view(JSP 페이지)에 결과 값을 출력한 후 요청한 클라이언트에 응답한다.
4. 서블릿 작성 규칙
- javax.servlet, javax.servlet.http, java.io 패키지를 임포트 한다.
- 서블릿 클래스는 반드시 public로 선언해야 하고, HttpServlet를 상속해야 한다.
- 사용자 요청을 처리하기 위해 doGet() 메서드나 doPost() 메서드를 반드시 오버라이딩 해야 한다.
- doGet() 또는 doPost() 메서드는 ServletException 과 IOException 예외를 던지도록 (throws) 선언한다.
- doGet() 또는 doPost() 메서드를 호출할 때의 매개변수는 HttpServletRequest 와 HttpServletResponse 를 사용한다.
5. 서블릿 작성
1) web.xml 에서 매핑
<servlet> <!-- 서블릿 등록 -->
<servlet-name>서블릿명</servlet-name>
<servlet-class>패키지를 포함한 서블릿 클래스명</servlet-class>
</servlet>
<servlet-mapping> <!-- 서블릿과 요청명 매핑 -->
<servlet-name>서블릿명</servlet-name>
<url-pattern>클라이언트 요청 URL</url-pattern>
</servlet-mapping>
예제) 요청을 처리할 서블릿 클래스
package servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setAttribute("message", "서블릿은 web-inf에 등록하고 해야하네.");
req.getRequestDispatcher("/13Servlet/HelloServlet.jsp").forward(req, resp);
}
}
2) @WebServlet 애너테이션으로 매핑
package servlet;
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("/13Servlet/AnnoMapping.do")
public class AnnoMapping extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("message", "@WebServlet으로 매핑");
req.getRequestDispatcher("/13Servlet/AnnoMapping.jsp").forward(req, resp);
}
}
6. 서블릿의 수명주기 메서드
- @Postconstruct : 객체 생성 직후 호출, 애너테이션을 사용하므로 메서드명은 개발자가 정함
- init() : 서블릿의 초기화 작업을 수행하기 위해 호출, 최초 요청시 딱 한번만 호출
- service() : 클라이언트의 요청을 처리 하기 위해 호출
- destroy() : 서블릿이 새롭게 컴파일 되거나, 서버가 종료될 때 호출
- @PreDestroy : 서블릿 객체를 제거하는 과정에서 호출
예제) 수명 주기 메서드 동작 확인
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>LifeCycle.jsp</title>
</head>
<body>
<script>
function requestAction(frm, met) {
if (met == 1) {
frm.method = 'get';
}
else {
frm.method = 'post';
}
frm.submit();
}
</script>
<h2>서블릿 수명주기(Life Cycle) 메서드</h2>
<form action="./LifeCycle.do">
<input type="button" value="Get 방식 요청하기" onclick="requestAction(this.form, 1);" />
<input type="button" value="Post 방식 요청하기" onclick="requestAction(this.form, 2);" />
</form>
</body>
</html>
예제) 수명주기 메서드 동작 확인용 서블릿
package servlet;
import java.io.IOException;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
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("/13Servlet/LifeCycle.do")
public class LifeCycle extends HttpServlet {
@PostConstruct
public void myPostConstruct() {
System.out.println("myPostConstruct() 호출");
}
@Override
public void init() throws ServletException {
System.out.println("init() 호출");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("service() 호출");
super.service(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("doGet() 호출");
req.getRequestDispatcher("/13Servlet/LifeCycle.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("doPost() 호출");
req.getRequestDispatcher("/13Servlet/LifeCycle.jsp").forward(req, resp);
}
@Override
public void destroy() {
System.out.println("destroy() 호출");
}
@PreDestroy
public void myPreDestroy() {
System.out.println("myPreDestroy() 호출");
}
}
댓글 없음:
댓글 쓰기