카테고리 없음

[유레카 / 백엔드] TIL - 8 (Spring)

coding-quokka101 2025. 11. 4. 09:17

Eclipse와 Tomcat으로 시작하는 서블릿 프로그래밍 - 설치부터 실행까지 🚀

 

**** 오늘의 학습 내용은 작성자가 나중에 헷갈리지 않게 공부, 기록 용으로 쓴 글입니다. ****
오늘은 웹 애플리케이션 개발의 핵심인 서블릿(Servlet) 프로그래밍에 입문했습니다! 이클립스 IDE와 아파치 톰캣 10.1 서버를 설치하고 설정하는 것부터, 실제로 동작하는 웹 애플리케이션을 만들고 Postman으로 테스트하는 과정까지 전부 경험했습니다.

처음에는 "이게 왜 이렇게 복잡하지?"라는 생각이 들었지만, 하나씩 따라하다 보니 웹 서버와 자바 애플리케이션이 어떻게 통신하는지 명확하게 이해할 수 있었습니다. 특히 서블릿의 복잡한 코드들이 모두 "톰캣(WAS)과의 약속"이라는 것을 깨닫는 순간이 가장 인상 깊었습니다.


📌 학습 목표

  • Apache Tomcat 10.1.48 설치 및 Eclipse 연동
  • Dynamic Web Project 생성 및 구조 이해
  • 정적 컨텐츠(HTML) 서빙 테스트
  • 첫 번째 서블릿 작성 및 실행
  • Postman을 이용한 API 테스트

🛠️ 1단계: Apache Tomcat 10.1.48 다운로드 및 설치

Tomcat이란?

Apache Tomcat은 자바 서블릿과 JSP를 실행할 수 있는 **WAS(Web Application Server)**입니다. 오늘 사용한 10.1.48 버전은 Jakarta EE 9 스펙을 지원하여 최신 서블릿 API를 사용할 수 있습니다.

다운로드 과정

Apache Tomcat 공식 다운로드 페이지에서 10.1.48 버전 선택

  1. Apache Tomcat 공식 웹사이트(https://tomcat.apache.org) 접속
  2. 좌측 메뉴에서 "Download" → "Tomcat 10" 선택
  3. "10.1.48" 버전의 Binary Distributions 섹션에서 "64-bit Windows zip" 다운로드
  4. 다운로드한 압축 파일을 원하는 경로에 압축 해제 (예: F:\software\dev\apache-tomcat-10.1.19)

💡 Tip: 설치 경로는 영문으로 된 경로를 사용하는 것이 좋습니다. 한글 경로는 나중에 문제를 일으킬 수 있어요!


⚙️ 2단계: Eclipse에서 Tomcat 서버 설정하기

Window > Show View > Servers

Eclipse 상단 메뉴에서 Window → Show View → Servers 선택

Eclipse에서 웹 애플리케이션을 실행하려면 먼저 서버를 등록해야 합니다.

  1. Eclipse 상단 메뉴에서 Window → Show View → Perspective → Servers 선택
  2. 하단에 "Servers" 탭이 생성됩니다

새로운 서버 추가



Servers 뷰에서 새로운 서버 추가

  1. Servers 뷰에서 빈 공간 우클릭 → New → Server 선택
  2. "Define a New Server" 창이 열립니다

Apache → Tomcat v10.1 Server 선택

  1. Server type에서 Apache → Tomcat v10.1 Server 선택
  2. "Next" 버튼 클릭

Tomcat 설치 경로 지정


Tomcat installation directory에 압축 해제한 경로 입력

  1. "Tomcat installation directory"에 앞서 압축 해제한 Tomcat 폴더 경로 입력
    • 예: C:\software\dev\apache-tomcat-10.1.19

2. "JRE"는 "Workbench default JRE" 선택

3. "Finish" 버튼 클릭

서버 시작하기


Servers 뷰에서 서버를 시작할 수 있는 플레이 버튼

Servers 뷰에 "Tomcat v10.1 Server at localhost"가 추가되었습니다!

  • 녹색 플레이 버튼: 서버 시작
  • 빨간 사각형 버튼: 서버 중지

Started, Synchronized 상태가 되면 서버가 정상적으로 실행된 것


📦 3단계: Dynamic Web Project 생성하기

Eclipse Marketplace에서 Web Tools 설치

Eclipse Web Developer Tools 설치

만약 Eclipse에 웹 개발 도구가 없다면:

  1. Help → Eclipse Marketplace
  2. "web" 검색
  3. "Eclipse Web Developer Tools 3.39" 설치

새 프로젝트 생성

File → New → Dynamic Web Project

  1. Eclipse 메뉴에서 File → New → Project → Dynamic Web Project 선택
  2. 또는 File → New → Dynamic Web Project 직접 선택

프로젝트 설정

WebBasic 프로젝트 생성 및 Tomcat 런타임 설정

  • Project name: WebBasic
  • Target runtime: Apache Tomcat v10.1 (앞서 등록한 서버)
  • Dynamic web module version: 6.0
  • Configuration: <custom>

"Finish" 버튼을 클릭하면 프로젝트가 생성됩니다!

프로젝트 구조 이해하기

WebBasic/
├── src/
│   └── main/
│       ├── java/          ← 서블릿 등 자바 코드
│       └── webapp/         ← HTML, CSS, JS 등 웹 리소스
│           ├── WEB-INF/
│           │   └── web.xml
│           └── index.html
└── build/
    └── classes/
  • src/main/java: 서블릿 클래스 등 자바 소스 코드 위치
  • src/main/webapp: HTML, CSS, JavaScript 등 정적 리소스 위치
  • WEB-INF: 외부에서 직접 접근할 수 없는 보안 영역

📄 4단계: 첫 번째 HTML 파일 만들기

index.html 생성

webapp 폴더에 index.html 생성

  1. WebBasic → src → main → webapp 폴더 우클릭
  2. New → HTML File 선택
  3. File name: index.html
  4. "Finish" 클릭

간단한 HTML 작성

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Welcome to WebBasic</title>
</head>
<body>
    <h1>index.html</h1>
    <p>첫 번째 웹 페이지입니다!</p>
</body>
</html>

서버에 프로젝트 추가

Servers 뷰에서 Modules 탭 확인

  1. Servers 뷰에서 "Tomcat v10.1 Server at localhost" 더블클릭
  2. 하단의 "Modules" 탭 클릭
  3. "Add Web Module..." 버튼 클릭


WebBasic 프로젝트를 서버에 추가

  1. "Web" 프로젝트 선택
  2. Path: /Web 또는 /WebBasic
  3. "OK" 클릭
  4. Ctrl + S로 서버 설정 저장

서버 시작 및 브라우저 확인

Source 뷰에서 서버 재시작

  1. Servers 뷰에서 서버 시작 (녹색 플레이 버튼)
  2. 웹 브라우저에서 http://localhost:8080/WebBasic/index.html 접속

브라우저에서 index.html이 성공적으로 표시됨

성공! 화면에 "index.html"이라는 제목이 표시되면 정적 파일 서빙이 정상적으로 작동하는 것입니다.

💡 파일 저장 팁: Eclipse에서 HTML이나 Java 파일을 수정한 후 Ctrl + S로 저장하면, Tomcat이 자동으로 변경사항을 감지하여 재배포합니다!


☕ 5단계: 첫 번째 서블릿 작성하기

서블릿이란?

**서블릿(Servlet)**은 자바를 사용하여 동적 웹 컨텐츠를 생성하는 서버 측 프로그램입니다. 클라이언트의 HTTP 요청을 받아 처리하고, 동적으로 응답을 생성할 수 있습니다.

HelloServlet.java 생성

  1. src/main/java 폴더 우클릭
  2. New → Package 선택
  3. Package name: servlet
  4. 생성된 servlet 패키지 우클릭
  5. New → Class 선택
  6. Class name: HelloServlet

HelloServlet 코드 작성

package servlet;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;

// 복잡하다. 상속... 재정의... throws 예외...@WebServlet
// 위 복잡한 내용이 의미하는 것? 톰캣(WAS)와 약속된 코드!
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
     
    // 클라이언트가 HTTP GET 방식으로 요청할 때
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        response.getWriter().append("Served at: ").append(request.getContextPath());
    }

    // 클라이언트가 HTTP POST 방식으로 요청할 때
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        doGet(request, response);
    }
}

코드 상세 분석

1. 패키지와 Import문

package servlet;
import jakarta.servlet.*;
  • 중요! Tomcat 10부터는 javax.servlet이 아닌 jakarta.servlet 패키지를 사용합니다
  • Jakarta EE 9 스펙 변경으로 인한 것으로, 이전 버전 Tomcat과 호환되지 않습니다

2. @WebServlet 어노테이션

@WebServlet("/hello")
  • 이 서블릿이 처리할 URL 패턴을 정의합니다
  • /hello로 요청이 들어오면 이 서블릿이 실행됩니다
  • 예전에는 web.xml에 설정을 작성했지만, 서블릿 3.0부터는 어노테이션으로 간단하게 처리 가능!

3. HttpServlet 상속

public class HelloServlet extends HttpServlet
  • 모든 서블릿은 HttpServlet 클래스를 상속받아야 합니다
  • 이것이 바로 **"톰캣(WAS)과의 약속"**입니다
  • 톰캣이 서블릿 생명주기를 관리할 수 있게 하는 규칙!

4. doGet() 메서드

protected void doGet(HttpServletRequest request, HttpServletResponse response)
  • HTTP GET 요청이 들어올 때 실행되는 메서드
  • HttpServletRequest: 클라이언트 요청 정보 (파라미터, 헤더 등)
  • HttpServletResponse: 클라이언트에게 보낼 응답 작성

5. doPost() 메서드

protected void doPost(HttpServletRequest request, HttpServletResponse response)
  • HTTP POST 요청이 들어올 때 실행되는 메서드
  • 현재는 doGet()을 호출하도록 구현했지만, 실제로는 각각 다른 로직을 구현합니다

🚀 6단계: 서블릿 실행 및 테스트

서버 재시작

  1. 파일 저장: Ctrl + S
  2. Servers 뷰에서 서버 재시작 (서버 우클릭 → Restart)

브라우저에서 테스트

브라우저 주소창에 입력:

http://localhost:8080/WebBasic/hello

결과: Served at: /WebBasic

성공! 서블릿이 정상적으로 실행되어 응답을 보낸 것입니다.


🔍 7단계: Postman으로 API 테스트하기

Postman이란?

Postman은 API 개발과 테스트를 위한 협업 플랫폼입니다. 브라우저 없이도 HTTP 요청을 쉽게 보낼 수 있어서, RESTful API 개발에 필수적인 도구입니다.

Postman 설치

  1. 공식 웹사이트(https://www.postman.com/downloads/) 접속
  2. Windows 버전 다운로드 및 설치

Postman으로 GET 요청 보내기

Postman에서 서블릿에 GET 요청 보내기

  1. Postman 실행
  2. 좌측 상단 "New""HTTP Request" 클릭
  3. 메서드: GET 선택
  4. URL 입력: http://localhost:8080/WebBasic/hello
  5. "Send" 버튼 클릭

응답 확인

Postman 하단의 "Body" 탭에서 응답 확인:

Served at: /WebBasic
  • Status: 200 OK
  • Time: 약 15-20ms
  • Size: 약 144 B

브라우저와 동일한 결과를 받았습니다! Postman을 사용하면 POST, PUT, DELETE 같은 다양한 HTTP 메서드를 쉽게 테스트할 수 있습니다.


💡 오늘의 핵심 깨달음

1. "복잡한 코드 = 톰캣과의 약속"

처음 서블릿 코드를 봤을 때는 상속, 재정의(Override), 예외 처리(throws) 등이 너무 복잡해 보였습니다. 하지만 이 모든 것이 톰캣(WAS)이 서블릿을 관리하기 위한 규칙이라는 걸 이해하고 나니 명확해졌습니다.

서블릿 생명주기(Lifecycle):

  1. 로딩(Loading): 서블릿 클래스를 메모리에 로드
  2. 인스턴스화(Instantiation): 서블릿 객체 생성
  3. 초기화(Initialization): init() 메서드 호출
  4. 요청 처리(Request Handling):
    • service() 메서드가 HTTP 메서드 판별
    • doGet() 또는 doPost() 호출
  5. 소멸(Destruction): destroy() 메서드 호출

톰캣이 이런 생명주기를 관리하기 때문에, 우리는 정해진 규칙(HttpServlet 상속, doGet/doPost 재정의)을 따라야 합니다.

2. javax vs jakarta 패키지

Tomcat 10부터는 javax.servlet에서 jakarta.servlet로 패키지명이 변경되었습니다. 이는 Jakarta EE로의 전환에 따른 것으로, 반드시 주의해야 합니다!

// ❌ Tomcat 10에서 오류 발생
import javax.servlet.*;

// ✅ Tomcat 10에서 정상 작동
import jakarta.servlet.*;

3. WAS의 역할

톰캣은 단순한 웹 서버가 아니라 자바 애플리케이션을 실행하는 컨테이너입니다:

  • 서블릿 생명주기 관리
  • HTTP 요청을 자바 객체로 변환
  • 멀티스레딩으로 동시 요청 처리
  • 세션 관리, 보안, 로깅 등 제공

4. 프레임워크가 필요한 이유

서블릿을 직접 작성하다 보니 다음과 같은 불편함을 느꼈습니다:

  • 반복적인 코드 (상속, 메서드 재정의)
  • 복잡한 설정 (web.xml 또는 어노테이션)
  • URL 매핑 관리의 어려움

이런 복잡함을 해결하기 위해 Spring Framework 같은 프레임워크가 등장했습니다. 프레임워크는 이러한 반복 작업을 추상화하여 개발자가 비즈니스 로직에 집중할 수 있게 해줍니다.

5. HTTP 메서드의 의미

GET과 POST의 차이를 이론으로만 알고 있었는데, 실제로 doGet()과 doPost() 메서드를 구현하면서:

  • GET: 데이터 조회 (멱등성, 캐싱 가능)
  • POST: 데이터 생성/수정 (멱등성 없음)

이 차이를 몸으로 느낄 수 있었습니다.


🎯 학습 중 발생한 문제와 해결

문제 1: 404 Not Found 오류

증상: 브라우저에서 서블릿 접속 시 404 오류 발생

원인:

  • 서버에 프로젝트가 추가되지 않았거나
  • URL 매핑이 잘못됨

해결:

  1. Servers 뷰 → 서버 더블클릭 → Modules 탭 확인
  2. Add Web Module로 프로젝트 추가
  3. URL 확인: /hello vs /Hello (대소문자 구분!)

문제 2: javax.servlet 패키지를 찾을 수 없음

증상: import javax.servlet.* 에서 컴파일 오류

원인: Tomcat 10은 jakarta.servlet 패키지 사용

해결:

// 변경 전
import javax.servlet.*;

// 변경 후
import jakarta.servlet.*;

문제 3: 코드 수정이 반영되지 않음

증상: 서블릿 코드를 수정했는데 브라우저에서 변경사항이 보이지 않음

해결:

  1. Ctrl + S로 파일 저장
  2. 서버 재시작: Servers 뷰에서 서버 우클릭 → Restart
  3. 브라우저 캐시 삭제: Ctrl + F5

🔥 앞으로의 학습 계획

오늘 배운 기초를 바탕으로 다음 주제들을 학습할 예정입니다:

1. JSP(JavaServer Pages)

서블릿만으로 HTML을 생성하는 것은 매우 불편합니다. JSP를 사용하면 HTML 안에 자바 코드를 삽입할 수 있어 뷰 개발이 훨씬 쉬워집니다.

<!-- 예시: JSP 파일 -->
<html>
<body>
    <h1>현재 시간: <%= new java.util.Date() %></h1>
</body>
</html>

2. 폼 데이터 처리

HTML form에서 전송한 데이터를 서블릿에서 받아 처리하는 방법:

String name = request.getParameter("name");
String email = request.getParameter("email");

3. 세션(Session)과 쿠키(Cookie)

HTTP는 무상태(Stateless) 프로토콜이므로, 사용자 상태를 유지하려면 세션이나 쿠키가 필요합니다.

4. 데이터베이스 연동

JDBC(Java Database Connectivity)를 사용하여:

  • 데이터베이스 연결
  • CRUD(Create, Read, Update, Delete) 구현
  • Connection Pool 관리

5. MVC 패턴

Model-View-Controller 패턴을 서블릿과 JSP로 구현하여:

  • Model: 비즈니스 로직과 데이터 (Java 클래스)
  • View: 화면 표시 (JSP)
  • Controller: 요청 처리 및 흐름 제어 (Servlet)

📚 참고 자료


📝 마치며

처음 서블릿을 접했을 때는 설정도 복잡하고 코드도 이해하기 어려웠습니다. 특히 "왜 이렇게 많은 것들을 상속받고 재정의해야 하지?"라는 의문이 들었죠.

하지만 **"이 모든 복잡함이 톰캣과의 약속이다"**라는 관점으로 보니 명확해졌습니다. 톰캣이 서블릿의 생명주기를 관리하고, HTTP 요청을 자바 객체로 변환하여 우리가 작성한 메서드에 전달하는 과정을 이해하고 나니, 왜 이런 규칙들이 필요한지 알 수 있었습니다.

또한 Tomcat 10부터 jakarta.servlet 패키지로 변경된 것도 중요한 포인트였습니다. 앞으로 레거시 코드를 볼 때 javax.servlet을 사용하는 부분들이 있을 텐데, 이제는 그 차이를 명확히 알고 대응할 수 있을 것 같습니다.

오늘 배운 서블릿은 Spring Framework를 배우기 전 반드시 알아야 할 기초입니다. 스프링의 DispatcherServlet도 결국 서블릿을 기반으로 하고 있으니까요. 기초를 탄탄히 다져서 더 발전된 웹 개발 기술로 나아가겠습니다!

부트캠프에서의 매일매일이 새로운 도전이고 배움입니다. 오늘도 한 걸음 더 성장했습니다! 💪