서블릿이란 자바 언어를 이용한 환경에서 컴포넌트(클래스) 기반으로 한 웹 애플리케이션 개발시 사용하는 기술이다. 서블릿은 주로 웹 서버에서 실행되며, 클라이언트의 요청에 응답하여 동적인 콘텐츠를 생성하거나 데이터베이스와 상호 작용하는 등의 작업을 수행한다.
서블릿을 관리하는 객체
서블릿 컨테이너가 시작될 때 혹은 해당 서블릿에 최초로 요청이 들어왔을 때 서블릿 클래스를 메모리에 로딩하며 로딩된 서블릿 클래스를 기반으로 서블릿의 인스턴스를 생성한다.
init()
메서드가 호출되어 초기화 작업을 수행한다.
클라이언트가 HTTP 요청시 서블릿 컨테이너는 해당 요청을 처리하기 위해 새로운 스레드를 생성하거나 Thread Pool에서 스레드를 가져온다. service()
메서드가 호출되어 요청을 처리하며, HTTP 메서드(DO, POST) 등에 따라 doGet()
, doPost()
를 수행한다. 개발자는 doGet()
, doPoast()
메서드를 오버라이딩하여 실제 로직을 구현한다.
서블릿은 클라이언트에게 응답을 생성한다. HttpServletResponse
객체를 사용하여 헤더 설정, 쿠키 추가, 출력 스트림을 이용한 응답 데이터 전송 등을 수행한다.
서블릿 컨테이너가 종료되거나 해당 서블릿의 생명 주기가 끝날 때, destroy()
메서드가 호출되어 마무리 작업을 수행한다.
Servlet의 문제점 대두
Servlet은 HTML 코드를 자바 코드 안에 문자열로 포함시키는데, 이로 인해 복잡하고 가독성이 떨어지며 비즈니스 로직과 프레젠테이션 로직이 혼재되어 있어 유지보수가 어렵다는 문제점이 있다.
JSP 등장과 한계
태그 기반 문법으로 HTML 코드와 자바 코드를 쉽게 통합할 수 있다. 그러나 여전히 로직과 프레젠테이션의 분리가 완벽하지 않았으며 코드가 복잡했다.
MVC 패턴 등장
Model, View, Controller 세가지 역할로 애플리케이션을 구조화하는 현재로써 가장 많이 사용되는 디자인 패턴이다.
참고 포스팅
HttpServlet 클래스를 상속받으면 그 클래스는 servlet이 된다.
service()
, doGet()
, doPost()
메서드 중 재정의 하면 되고, 주로 doGet()
이나 doPost()
메서드를 많이 사용한다.
get 방식: 서버 요청시 URL에 데이터가 노출되기 때문에 보안성이 낮으며 파일 업로드 불가
Post 방식: URL에 데이터가 노출되지 않아 상대적으로 보안성이 높으며 많은 양의 데이터를 보낼 때 유용하고 파일 업로드 가능
init()
으로 실행된 건 서블릿 컨테이너가 관리하면서 메모리에 계속 남아있다.
서버 재부팅 등 메모리에서 잠깐 사라질 때 destroy()
가 자동으로 실행한다.
두번째 실행부터 init()
을 실행하지 않고 service()
를 실행한다.
서블릿 컨테이너에 기재한 내용과 같지만 다시 짚고 넘어가기!
init()
호출service()
호출HttpServletRequest
객체와 HttpServletResponse
객체를 생성하여 파라미터로 넘김service()
는 전송 방식(GET, POST)을 체크하여 그것에 맞는 메서드를 자동으로 호출doGet()
, doPost()
, doPut()
, doDelete()
등HttpServletRequest
객체와 HttpServletResponse
객체는 자동 소멸destroy()
호출
- Java에서 서블릿 정의시 사용되는 어노테이션
- web.xml 파일을 통한 서블릿 매핑을 대체할 수 있어 코드가 간결해짐
- 서블릿 클래스에 직접 적용되며 서블릿이 처리해야 할 URL 패턴과 기타 설정 지정 가능
JSP
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<script type="text/javascript">
window.onload = function() {
document.getElementById("getBtn").addEventListener("click", function() {
location.href = "<%=request.getContextPath() %>/servletTest02.do";
});
}
</script>
<body>
<h2>Servlet요청 연습</h2>
<br><hr><br>
<h3>Get 방식 요청1 (링크 방식)</h3>
<a href="<%=request.getContextPath() %>/servletTest02.do">Get 방식 요청1</a>
<hr>
<h3>Get 방식 요청2 (form 태그 방식)</h3>
<form action="<%=request.getContextPath() %>/servletTest02.do">
<input type="submit" value="Get 방식 요청2">
</form>
<hr>
<h3>Get 방식 요청3 (javascript 방식)</h3>
<form>
<input type="button" value="Get 방식 요청3" id="getBtn">
</form>
<h3>Post 방식 요청 (form 태그 방식)</h3>
<form action="<%=request.getContextPath() %>/servletTest02.do" method="post">
<input type="submit" value="Post 방식 요청">
</form>
</body>
</html>
Servlet
package servlet.test;
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("/servletTest02.do")
public class ServletTest02 extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void init() throws ServletException {
System.out.println(this.getServletName() + "에서 init() 메서드 호출");
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("service() 메서드 시작..");
String method = request.getMethod();
if("GET".equals(method)) {
doGet(request, response);
} else if("POST".equals(method) ) {
doPost(request, response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doGet() 메서드 시작..");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html; charset=utf-8");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head><meta charset='utf-8'></head>");
out.println("<body><h2>doGet() 메서드에서 처리한 내용</h2></body>");
out.println("</html>");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("doPost() 메서드 시작..");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html; charset='utf-8'");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head><meta charset='utf-8'></head>");
out.println("<body><h2>doPost() 메서드에서 처리한 내용</h2></body>");
out.println("</html>");
}
@Override
public void destroy() {
System.out.println(this.getServletName() + "에서 destroy() 메서드 호출");
}
}