Servlet이란?
Servlet에 대해서 한마디로 정리하자면 다음과 같이 말할 수 있다.
클라이언트의 Request를 처리하고, 이에 대한 Response를 제공해주도록 해주는 자바 클래스이자 웹 프로그래밍 기술
자바 기반 프레임워크로 많이 사용되는 Spring Boot 프레임워크도 내부적으로는 Servlet 기반으로 동작된다. 일반적으로 Tomcat이라는 내장 Servlet 컨테이너를 통해 서버를 구동시킨다.
Servlet의 기능
1.
요청 처리 및 응답 생성: Servlet은 HTTP 요청을 처리하고, 이에 대한 응답을 생성한다. 요청에는 다양한 정보가 포함되고, 프로그래머는 이를 HttpServletRequest 라는 인터페이스를 통해 접근할 수 있다. 응답은 HttpServletResponse 인터페이스를 통해 생성된다.
2.
생명주기 관리: Servlet의 생명주기는 컨테이너에 의해 관리된다. 컨테이너는 초기화를 위해 init 메소드를 호출하고, 각 요청에 대해서 service 메소드를 호출한다. 마지막으로, Servlet이 더 이상 필요하지 않은 경우, destroy 메소드를 호출해 리소스를 해제한다.
3.
세션 관리: Servlet은 HTTP 세션 관리 기능을 제공한다.
→ 3장에서 자세히 다룰 예정입니다!
4.
멀티 스레딩 지원: 컨테이너는 멀티 스레딩을 이용해 여러 클라이언트 요청을 동시에(concurrently) 처리할 수 있도록 지원한다.
Servlet 동작 원리
(망나니 개발자 tistory)
1.
클라이언트가 HTTP 프로토콜을 이용해 GET, POST 등의 요청을 보내면, HTTP 요청이 Servlet 컨테이너 로 전송된다.
2.
Servlet 컨테이너는 HttpServletRequest와 HttpServletResponse라는 객체를 생성한다.
3.
web.xml 파일의 내용을 바탕으로 사용자의 요청이 어느 servlet에 대한 요청인지를 확인한다. (endpoint 등을 통해)
4.
doGet()이나 doPost() 등의 메소드가 구현되어있다면 동적으로 페이지를 생성 후, HttpServletResponse 객체를 통해 응답을 전송한다.
5.
응답이 종료되면, HttpServletRequest와 HttpServletResponse 객체를 소멸시킨다.
Servlet 컨테이너의 생명주기
(망나니 개발자 tistory)
Servlet 객체의 생성과 소멸은 모두 Servlet 컨테이너가 담당한다. (init(), destroy())
C++의 생성자와 소멸자와 비슷한 느낌으로 프로그래머는 init과 destroy를 Override하여 Servlet 객체가 생성하거나 소멸하는 시점에 공통적으로 진행하고 싶은 작업을 설정할 수 있다. (ex. 로그 남기기 등)
즉, Servlet 컨테이너도 일종의 IoC(Inversion of Control) 가 적용된 기술이다. 프로그래머는 오직 요청에 따른 어떤 동작을 수행할 지 등 도메인에만 집중할 수 있도록 해준다.
프로그래머는 service() 메소드를 Override하여 요청에 따른 분기 처리(doGet(), doPost() 등)를 수행할 수 있고, doGet()이나 doPost() 메소드를 Override하여 해당 endpoint에 대한 로직을 작성할 수 있다.
javax.servlet.http.HttpServlet.java
만약 프로그래머가 doXXX() 메소드를 구현하지 않는다면 해당 enpoint에 대한 HTTP 메소드는 지원하지 않음을 의미한다.
따라서 이 경우 HTTP 1.1 이후 프로토콜에서는 405 Method Not Found를 응답하게 되고, 그 외는 400 Bad Request를 응답하게 된다.
Servlet과 Tomcat을 이용하여 웹서버 구축
개발환경은 IntelliJ IDEA Ultimate이며, Jakarta EE를 이용하여 빠르게 구축하였다.
Servlet 컨테이너로 Tomcat을 이용했다. MacOS 환경이라면 Core의 tar.gz를 받으면 된다!
방금 설치한 Tomcat의 경로를 설정하였고, 빌드 툴로는 Gradle을 이용하였다.
Java EE 8 버전을 선택하고, 종속성은 Servlet만 선택했다.
HelloServlet.java
이런식으로 Servlet 클래스가 만들어진다.
HttpServlet을 extends하며 필요한 경우 init()과 destory()를 Override할 수 있다.
doGet()을 구현하여 GET 메소드를 지원하였고, 간단한 페이지를 만들어 응답으로 건내주도록 작성했다.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</servlet>
</web-app>
XML
복사
web.xml
원래는 다음과 같은 webapp/WEB-INF/web.xml 파일에 servlet을 직접 등록해주어야 클래스와 endpoint가 제대로 매핑이 된다.
하지만 javax.servlet.annotation의 @WebServlet 어노테이션을 클래스 위에 달면, 편하게 클래스와 endpoint 매핑을 진행할 수 있다.
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>JSP - Hello World</title>
</head>
<body>
<h1><%= "Hello World!" %></h1>
<br/>
<a href="hello-servlet">Hello Servlet</a>
</body>
</html>
XML
복사
index.jsp
우측 상단의 구성 편집을 클릭하여, 실행/디버그 관련 설정을 할 수 있다.
Tomcat 버전을 설정하거나 Home URL을 설정할 수 있고, Tomcat 서버를 구축할 포트번호를 지정할 수도 있다.
Tomcat 서버를 실행하여 이런 화면이 나온다면 성공한 것이다! (무섭게 빨간 글씨로 되어 있는 부분이 있는데 내용을 읽어보면 단순 로그이다.. )
이제 브라우저를 열어 localhost:8080에 접속하면…
이런식으로 홈화면이 나온다!