서블릿

동적 웹 페이지를 만들 때 사용되는 자바 기반의 웹 애플리케이션 프로그래밍 기술이다. 서블릿은 웹 요청과 응답의 흐름을 간단한 메서드 호출만으로 체계적으로 다룰 수 있게 해준다.
서버에서 실행되다가 웹 브라우저에서 요청을 하면 해당 기능을 수행한 후 웹 브라우저에 결과를 전송한다.
클라이언트의 HTTP 요청을 받고 응답을 생성해서 돌려주는 역할을 한다.

 

일반적으로 웹서버는 정적인 페이지만을 제공하지만 동적인 페이지의 제공을 위해 도와주는 것이 서블릿이며,
동적인 페이지를 생성하는 어플리케이션이 CGI 이다.

 

동적페이지란?
정적페이지는 글자와 이미지 등이 고정적으로 있는 페이지이다. 내용이 항상 똑같다.
하지만 동적페이지는 요청때마다 내용이 변경될 수 있다. (게시판 페이지는 항상 글이 바뀌므로 동적페이지)

 

<CGI>

 CGI (Common GateWay Interface)
서버가 외부 프로그램을 실행해서 동적인 웹페이지를 생성할 수 있게 하는 기술

 

- 동작방식
1.사용자가 요청
2.웹 서버가 CGI 스크립트를 "외부 프로세스"로 실행
3.CGI 프로그램이 출력으로 HTML 생성
4.그 결과를 브라우저로 전달

 

CGI 스크립트를 아래와 같이 되어있음

print "Content-type: text/html\n\n";
print "<html><body>";
print "<h1>Hello from CGI!</h1>";
print "</body></html>";

 

이 코드를 hello.cgi로 저장하고, /cgi-bin 같은 경로에 올려
브라우저에서 http://yourserver.com/cgi-bin/hello.cgi 요청하면 실행됨
출력 결과는 브라우저에 HTML로 보임
CGI는 브라우저 요청을 "실행 파일로 넘겨서", 그 표준 출력(stdout) 결과를 HTML처럼 보여주는 구조

 

하지만 요청마다 새로운 프로세스를 생성하므로 느리다. N명이 접속하면 N개의 프로세스가 뜨므로 비효율적이다.
그래서 서블릿이 등장하였다.
서블릿은 CGI와 다르게 요청마다 프로세스를 생성하는 것이 아닌, 한번만 로딩후 이후에는 쓰레드를 통해 처리한다.

 

 

<Servlet>

 

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("<html><body>");
        out.println("<h1>Hello from Servlet!</h1>");
        out.println("</body></html>");
    }
}

 

동작과정

 

1.사용자(클라이언트)가 URL을 입력하면 HTTP Request가 Servlet Container로 전송합니다.

 

http://localhost:8080/myapp/hello
이 요청이 HTTP Request로 서버(Tomcat)에 전송

2.요청을 전송받은 Servlet Container는 HttpServletRequest, HttpServletResponse 객체를 생성합니다.

 

요청 파라미터, URL 정보, 세션, 헤더 등은 request 객체
클라이언트에게 돌려줄 응답 내용은 response 객체
이 두 객체는 서블릿 컨테이너(Tomcat) 가 직접 만들어서 서블릿에게 전달

 

3.web.xml을 기반으로 사용자가 요청한 URL이 어느 서블릿에 대한 요청인지 찾습니다.

 

서블릿 컨테이너는 "이 URL은 어떤 서블릿이 처리해야 해?" 를 web.xml에서 찾음

<servlet>
  <servlet-name>hello</servlet-name>
  <servlet-class>com.example.HelloServlet</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/hello</url-pattern>
</servlet-mapping>

 

 

4.해당 서블릿에서 service메소드를 호출한 후 클리아언트의 GET, POST여부에 따라 doGet() 또는 doPost()를 호출합니다.


public void service(HttpServletRequest req, HttpServletResponse res) {
    if (req.getMethod().equals("GET")) {
        doGet(req, res);
    } else if (req.getMethod().equals("POST")) {
        doPost(req, res);
    }
}

이 흐름은 HttpServlet 클래스에 이미 구현되어 있어서
서블릿은 보통 doGet()이나 doPost()만 오버라이드해서 로직을 짬.

 

* doGet vs doPost
get은 URL에 데이터가 실려가고, post는 요청 본문에 숨겨서 보낸다.

 

5.doGet() or doPost() 메소드는 동적 페이지를 생성한 후 HttpServletResponse객체에 응답을 보냅니다.

protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
    res.setContentType("text/html");
    PrintWriter out = res.getWriter();
    out.println("<h1>Hello, " + req.getParameter("name") + "</h1>");
}

 

HTML 생성 → response 객체에 write()
톰캣이 그 응답을 브라우저로 전송함

 

6.응답이 끝나면 HttpServletRequest, HttpServletResponse 두 객체를 소멸시킵니다.

 

주요 특징
- 클라이언트의 Request에 의하여 동적으로 동작하는 컴포넌트
- JAVA의 스레드를 이용하여 동작
- MVC패턴에서 컨트롤러로 이용

 

 

<서블릿컨테이너>

서블릿을 실행시켜주는 프로그램
즉, 서블릿을 위한 실행 환경이자 관리자

HTTP 요청을 받아서,
서블릿을 대신 실행하고,
응답을 만들어 브라우저로 보내주는 녀석

 

서블릿은 HTML 을 만들어 응답해주는 도구가 아니다.

그저 요청을 받고 응답을 만들어주는 기본 구조일 뿐이다. HTML은 템플릿이 처리하고 데이터는 스프링이 처리한다.

 

* 결론 

서블릿은 요청이 들어왔을 때 URL을 분석해서
해당 서블릿 클래스의 service() → doGet() 또는 doPost()를 호출하고,
직접 응답을 만들어서 브라우저로 보내는 구조

 

하지만

어떤 URL 요청에서 내가 응답을 직접 만든적이 없는데?

그렇다. 요즘은 서블릿 위에 추상화 계층을 만들어 Spring MVC 형태로 사용된다.

 

@GetMapping("/hello")
public String hello(Model model) {
    model.addAttribute("name", "홍길동");
    return "hello"; // templates/hello.html → Thymeleaf가 HTML 만들어줌
}

 

- 요청은 여전히 서블릿을 통해 들어온다

스프링부트는 DispatcherServlet 이라는 중앙 관리 서블릿을 자동으로 등록한다.

URL에 맞는 @Controller 메서드 실행 하여서 Model 에 값을 담는다.

그 후, ViewResolver가 응답용 HTML을 찾아서 렌더링 해준다.

 

 

스프링MVC에서의 요청에 대한 처리 흐름

 *요청에 대한 기본흐름

DispatcherServlet
           ├── HandlerMapping     ← 어떤 컨트롤러 메서드를 호출할지 결정
           ├── HandlerAdapter     ← 그 메서드를 어떻게 호출할지 결정
           ├── Controller         ← 실제 요청 처리 실행
           ├── ViewResolver       ← 어떤 화면(HTML, JSP, 등)을 보여줄지 결정
           └── 응답(Response)

 

 

1. DispatcherServlet

HTTP 프로토콜로 들어오는 모든 요청을 가장 먼저 받아 적합한 컨트롤러에 위임해주는 프론트 컨트롤러

Servlet 시절에는 주소마다 서블릿을 web.xml에 직접 등록하여 연결하는게 너무 불편했지만

현재는 오직 DispatcherServlet 하나만 등록하여서 이것을 통해 처리한다.

 

2. HandlerMapping (인터페이스)

어떤 Controller 메서드를 실행할지 결정
Spring은 내부적으로 @ReqeustMapping, @GetMapping 같은 매핑 정보들을 다 저장하고 
사용자가 /hello 요청을 보내면 HandlerMapping가 찾아주는 것.

 

@GetMapping("/hello")
public String hello() { ... }

 

/hello 요청 들어오면 HandlerMapping이 이 메서드 찾아줌

 

중요한 두 가지 구현체가 있다.  


1. RequestMappingHandlerMapping → @RequestMapping, @GetMapping, @PostMapping 처리
2. SimpleUrlHandlerMapping → 정적 리소스 요청에 대한 매핑

 

 

3. HandlerAdapter


HandlerMapping이 찾아준 컨트롤러 메서드를 실제로 실행시켜주는 역할
컨트롤러 메서드의 파라미터 분석 (@RequestParam, @ModelAttribute, @RequestBody, ...)
바인딩 처리를 하고 실제 메서드 호출한다.

 

4. Controller

@GetMapping("/hello")
public String hello(Model model) {
    model.addAttribute("name", "홍길동");
    return "hello"; // View 이름
}

 

컨트롤러는 "처리 로직"만 담당하고, 응답을 직접 만들지 않음
→ 리턴된 "hello"는 실제 HTML이 아님, 뷰 이름이다.

 

5. ViewResolver


컨트롤러가 리턴한 "hello" 같은 뷰 이름을 HTML 파일 경로로 바꿔주는 애

 

return "hello" --> /templates/hello.html 처럼 실제 파일 경로로 바꿔서 그 파일을 렌더링 해준다.

보통 spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
이렇게 설정되어서
return "hello" -> classpath:/templates/hello.html 이렇게 처리된다.

'Spring' 카테고리의 다른 글

Redis를 활용한 Jwt 발급 (refreshtoken, rotate)  (0) 2025.04.10
[Spring] IOC , DI  (0) 2025.04.02
Spring Security  (0) 2025.02.24
Component  (0) 2024.10.15
스프링 MVC란?  (0) 2024.10.14

+ Recent posts