1. 개발 환경 구축 및 WAR 빌드/배포 절차
1) STS4 자바 엔터프라이즈 플러그인 설치
순수 서블릿 및 웹 기능(Dynamic Web Project) 개발을 위해 플러그인이 필요함.
- Help ▶️ Eclipse Marketplace... 선택
- Find 검색창에 Eclipse Enterprise Java 검색
- 마켓플레이스에서 검색 결과로 나오는 Eclipse Enterprise Java and Web Developer Tools 설치 후 STS4 재시작
💡 Spring Boot 기반으로 나온 STS4는 기본적으로 순수 Dynamic Web Project(레거시 서블릿) 메뉴가 포함되어 있지 않음
2) 프로젝트 환경(빌드)별 WAR 파일 추출 방법
- 빌드 도구가 없는 순수 서블릿 (일반 Dynamic Web Project):
- Project Explorer에서 원하는 프로젝트 우클릭 ▶️ Export ▶️ WAR file (※ 플러그인을 깔아야 이 메뉴가 보임)
- 생성 경로 및 배포: 지정한 목적지 경로에 생성
- Maven을 사용하는 경우 (pom.xml이 존재):
- pom.xml 상단에 war 확인
- 프로젝트 main 코드 환경 우클릭 ▶️ Run As ▶️ Maven clean 실행 (이전 빌드 지움)
- 위와 마찬가지로 우클릭 ▶️ Run As ▶️ Maven install (또는 package)
- 생성 경로 및 배포: 프로젝트 내 target/ 폴더 내 자동 생성
- Gradle을 사용하는 경우 (build.gradle이 존재):
- build.gradle 파일 상단 plugins { ... } 블록에 id 'war' 추가
- 우측 Gradle Tasks 탭 실행
(※ 안 보인다면 Window > Show View > Other > Gradle Tasks 선택) - 프로젝트 이름 ▶️ build 그룹 안의 war 혹은 build 더블 클릭하여 실행
- 생성 경로 및 배포: 프로젝트 내 build/libs/ 폴더 내 자동 생성
3) 아파치 톰캣 서버 실행 테스트
- Tomcat 다운로드: Apache Tomcat 공식 홈페이지에서 압축 파일(.zip) 형태로 다운로드 (인스톨러 미사용)
- 압축 해제: 반디집 등을 이용해 원하는 경로에 압축 해제
- 서버 구동: bin 디렉토리 안의 startup.bat (배치 파일) 실행
- 브라우저 접속 및 네트워크 메커니즘: 프롬프트 창(앱)을 끄지 않은 상태에서 브라우저에 localhost:8080 입력 후 접속
- 루프백(Loopback) 통신: 외부 네트워크 나갈 필요 없이 내 컴퓨터(로컬) 내부에서 돌고 도는 통신.
- OSI 7계층 기준: 물리적인 데이터 전송(1, 2계층) 단계가 필요 없고, 네트워크 계층(3계층, IP: 127.0.0.1) 단계에서 곧바로 자기 자신에게 패킷을 보냄.
- TCP/IP 4계층 기준: 애플리케이션(4) ➔ 전송(3) ➔ 인터넷(2) 계층까지만 내려간 뒤, 다시 역으로 올라와 내부 서블릿 컨테이너로 연결됨.
- 서버 종료: 구동 배치 파일과 한 쌍으로 존재하는 shutdown.bat 실행
- 루프백(Loopback) 통신: 외부 네트워크 나갈 필요 없이 내 컴퓨터(로컬) 내부에서 돌고 도는 통신.
⚠️포트 충돌(Port Conflict)
하나의 네트워크 포트(8080)에는 한 번에 하나의 프로세스만 바인딩(점유)할 수 있으므로, 다른 애플리케이션이 이미 해당 포트를 쓰고 있다면 톰캣 서버는 구동되지 못하고 에러가 발생
2. 자카르타 EE 서블릿 구동 메커니즘
1) 서블릿 실행 5단계 흐름 (레거시 기반)
- 클래스 정의: 자바 엔터프라이즈(Jakarta EE)의 HttpServlet 클래스를 상속받아 doGet() 또는 doPost()를 오버라이딩.
- 패키징 (아래 첨부파일 확인): 화면을 담당할 JSP나 자바 컴파일 파일(.class)들을 묶어 helloservlet.war 배포 파일을 생성.
- 톰캣 배치: 톰캣 디렉토리 내 webapps/ 폴더에 WAR 파일을 넣고 bin/startup.bat을 실행. (종료 시에는 shutdown.bat 사용)
- *언팩 (Unpack): 톰캣이 구동되면서 WAR 파일 압축을 자동으로 해제하고 고유 구조(WEB-INF/classes/ 내부의 컴파일된 파일들)를 호스팅 영역으로 인지.
- 요청 처리: localhost:8080/helloservlet/sayhello로 요청 시, 톰캣이 web.xml(서블릿 규격 명세서)을 파싱하여 배포 서블릿의 FQCN(완전 정규화된 클래스 경로, 예: mypkg.HelloServlet)과 sayhello URL 패턴을 매핑한 후, doGet() 내부의 코드(out.println()) 결과물을 HTTP 응답 바디에 실어 브라우저로 반환.
💡 요즘은 web.xml 대신 @WebServlet("/sayhello") 어노테이션을 사용하는 방식이 더 주류
더보기
💡 톰캣 구동 이후
- 톰캣의 자동 배포(Auto Deploy) 기능: 톰캣이 구동되거나 실행 중일 때 webapps/ 폴더를 주기적으로 감시한다. 이 폴더에 새로운 .war 파일이 들어오면, 톰캣 내부의 Host 배포기(Deployment 구동체)가 이를 감지하고 자동으로 압축을 풀어 버림.
- 압축을 푸는 이유: 자바 웹 애플리케이션이 실행되려면 WEB-INF/classes/ 안에 있는 컴파일된 클래스 파일들과 WEB-INF/lib/ 안의 라이브러리(.jar) 파일들을 자바 가상머신(JVM)이 읽을 수 있어야 함. 톰캣이 이 구조를 인식할 수 있도록 호스팅 영역에 압축을 풀어놓는 것.
2) 핵심 객체 및 컴포넌트 개념 비교
- HttpServletRequest / HttpServletResponse: 톰캣 웹서버가 클라이언트의 텍스트 요청(헤더+바디)을 받아 자바 객체로 변환해 서블릿의 파라미터(아규먼트)로 채워줌. 개발자가 response 객체의 out 스트림에 바디를 작성하면, 톰캣이 이를 기반으로 HTTP 응답 패킷을 완성한다.
- 서블릿 컨테이너(Servlet Container) vs 서블릿 컨텍스트(ServletContext):
- 서블릿 컨테이너: 서블릿이 실행되고 관리되는 실질적인 시스템 환경으로, 요청을 알맞은 서블릿에 매핑하고 서블릿의 생명주기(생성, 초기화, 요청 처리, 소멸)를 전반적으로 관리하는 주체/핵심컴포넌트
- 엄밀히 말하면, 톰캣의 핵심 서블릿 컨테이너 엔진(통칭 *카탈리나, Catalina)이 이 역할을 총괄하며, 내부적으로 내부 아키텍처(Engine, Host, Context, Wrapper)를 통해 요청을 분배하고 서블릿을 구동한다.
- 자바 엔터프라이즈(Jakarta EE) 명세에서 서블릿이 실행되는 환경을 서블릿 컨테이너 또는 서블릿 런타임 환경이라고 부름
- 서블릿 컨텍스트: 하나의 웹 애플리케이션(하나의 WAR 파일 단위) 영역 전체를 관리하고 공유 자원을 담는 컨테이너 내부의 환경(컨텍스트) 정보입니다.
- 서블릿 컨테이너: 서블릿이 실행되고 관리되는 실질적인 시스템 환경으로, 요청을 알맞은 서블릿에 매핑하고 서블릿의 생명주기(생성, 초기화, 요청 처리, 소멸)를 전반적으로 관리하는 주체/핵심컴포넌트
- 정적 서버(Apache, Nginx) vs 동적 서버(Tomcat): 정적 서버는 고정된 HTML/JS 리소스를 프록시 환경에서 빠르게 서비스하며, AJP 프로토콜 등을 통해 톰캣 전단에 서기도 함. 반면 톰캣은 요청에 따라 실시간으로 변화하는 동적 페이지를 생성.
- Forward Proxy/Reverse Proxy 환경에서 Apache/Nginx가 앞단에 서고 톰캣이 뒷단에서 동적 처리를 하는 구조
더보기
ℹ️ 카탈리나 자세히
1) 톰캣과 카탈리나의 관계
- 톰캣(Tomcat)이란? 웹 서버 기능(HTTP 요청 받기) + 서블릿 컨테이너 기능을 합친 전체 WAS(Web Application Server)의 이름.
- 카탈리나(Catalina)란? 이 톰캣 프로그램 내부에서 서블릿 사양을 실제로 구현하고 관리하는 본체(서블릿 컨테이너 엔진)의 이름.
2) 카탈리나 서블릿 컨테이너 내부 (계층적 구조)
카탈리나 서블릿 컨테이너 내부는 계층적 구조로 이루어져 있다. Engine ➔ Host ➔ Context ➔ Wrapper 순으로 상위에서 하위로 연결
Engine (최상위 엔진)
└── Host A (도메인: example.com)
│ ├── Context 1 (웹앱: /shop)
│ │ ├── Wrapper X (서블릿: OrderServlet)
│ │ └── Wrapper Y (서블릿: ProductServlet)
│ └── Context 2 (웹앱: /board)
│ └── Wrapper Z (서블릿: BoardServlet)
└── Host B (도메인: admin.example.com)
└── Context 3 (웹앱: /ROOT)
└── Wrapper W (서블릿: AdminServlet)
- Engine: 카탈리나 컨테이너의 최상위 컴포넌트. 알맞은 가상 호스트(Host)로 요청을 전달하는 대형 라우터(중앙 제어 장치) 역할을 한다.
- 특징: 톰캣 내부에서 알맞은 커넥터(Connector)로부터 요청을 넘겨받아 중심에서 처리한다.
- 하나 이상의 Host(가상 호스트)를 자식으로 포함.
- 엔진 레벨에서 정의된 설정(예: 로깅, 밸브 등)은 하위의 모든 호스트와 컨텍스트에 상속.
- 특징: 톰캣 내부에서 알맞은 커넥터(Connector)로부터 요청을 넘겨받아 중심에서 처리한다.
- Host: www.naver.com 같은 네트워크상 가상 호스트(도메인)를 뜻함.
- 특징:
- 하나의 톰캣 서버에서 여러 개의 도메인(예: www.example.com, api.example.com)을 독립적으로 서비스할 수 있게 해줌.
- 각 호스트는 내부에 여러 개의 Context(웹 애플리케이션)를 자식으로 포함.
- 톰캣 설정 파일(server.xml)의 <Host> 태그와 매핑.
- 특징:
- Context: 하나의 웹 애플리케이션(WAR 파일 하나) 단위.
- 특징:
- 가장 친숙한 단위인 WAR 파일 또는 특정 웹 루트 디렉터리와 1:1로 매핑.
- 각 Context는 자신만의 고유한 서블릿 컨텍스트(ServletContext) 경로(예: /shop, /blog)를 가짐.
- 내부적으로 웹 애플리케이션에 포함된 여러 개의 Wrapper(서블릿)를 자식으로 관리.
- 특징:
- Wrapper: 가장 하위 단계의 컨테이너로, 개별 서블릿 하나하나를 감싸서 관리하는 컴포넌트.
- 특징:
- 서블릿 인스턴스의 생명주기(init, service, destroy)를 직접 감싸서 실행하고 관리.
- 서블릿은 카탈리나 컨테이너 구조에 직접 참여할 수 없기 때문에, Wrapper가 서블릿을 감싸서 컨테이너의 구성원으로 만들어 주는 역할.
- 특징:
ℹ️ 덧붙임: Valve (밸브)와 Pipeline (파이프라인)
카탈리나가 이 계층 구조를 따라 요청을 전달할 때, 각 컨테이너(Engine, Host, Context, Wrapper)는 내부에 Pipeline을 가지고 있음. 이 파이프라인 안에는 Valve라는 부품들이 직렬로 연결되어 있어, 요청이 하위 컨테이너로 넘어가기 전에 인증, 로깅, IP 제한 같은 전처리 작업을 수행. (서블릿의 Filter와 유사하지만, 톰캣 자체에 종속된 기능.)
'Tech Stack > Backend' 카테고리의 다른 글
| 🥾디스패처 서블릿 (레거시 방식과 REST API 방식) (0) | 2026.06.25 |
|---|---|
| 🥾 레거시와 Spring Boot 웹 서버 구동 방식 비교 (+ REST API) (0) | 2026.06.25 |
| 🍃스프링, 자바 표준, 자카르타 세 진영의 어노테이션 비교 (0) | 2026.06.24 |
| 🥾Spring Boot 시작하기 (개발 환경 구축) (0) | 2026.06.23 |
| 🍃어노테이션 기반 자동 빈 등록(Component Scan & Autowired) (1) | 2026.06.21 |