본문 바로가기

JAVA

[Java] 자바 웹 기술의 역사

 


 

Servlet의 등장 (1997)

등장 이유 :

  • 1990년대 후반 CGI(Common Gateway Interface)는 각 요청마다 프로세스를 새로 생성해야 했기 때문에 성능 문제가 심각했습니다.
  • 이를 해결하기 위해 자바 기반의 고성능, 멀티스레드 방식 웹 서버 기술이 필요했습니다.

개요 :

  • 자바로 작성된 서버 측 프로그램으로, 웹 요청을 처리하고 동적 콘텐츠를 생성합니다.
  • `javax.servlet` 패키지를 기반으로 동작합니다.
  • 서블릿 컨테이너 (ex: Tomcat) 위에서 실행됩니다.

단점 :

  • HTML을 자바 코드 내에서 직접 작성해야 해 유지보수성, 가독성이 낮습니다.
  • 비즈니스 로직과 뷰(HTML) 코드가 섞입니다.

 

더보기

CGI 기본 개념 요약

  • CGI는 웹 서버가 외부 프로그램을 실행해서 동적인 콘텐츠를 생성하는 방식입니다.
  • 각 HTTP 요청마다 외부 프로그램을 새로 실행합니다.
  • 이 프로그램은 보통 Perl, Python, Bash, C 같은 스크립트 언어나 시스템 언어로 작성됩니다.

 

파이썬 CGI 예시 코드

# hello.py
#!/usr/bin/env python3
print("Content-Type: text/html\n")
print("<html><body><h1>Hello from Python CGI</h1></body></html>")
  • 누군가 웹사이트에 접속해서 `hello.py`를 요청 → 웹 서버는 Python 인터프리터를 실행해서 hello.py를 한번 실행합니다.
  • 또 누군가 접속해서 `hello.py`를 요청 → 다시 Python 인터프리터를 실행해서 똑같은 파일을 또 실행합니다.
  • 그래서 사용자 100명이 동시에 접속하면 Python 인터프리터도 100번이 실행됩니다. (문제!!)

 

동작 방식

  • 사용자가 웹 브라우저에서 `http://example.com/cgi-bin/hello.pl` 요청
  • 웹 서버는 `hello.pl`을 별도의 프로세스로 실행합니다.
  • 이 프로세스가 출력한 텍스트(HTML)를 웹 서버가 받아서 응답으로 클라이언트에 전송합니다.
  • 다음 요청이 오면 또 새로 실행합니다. (비용이 큼)

 

성능 문제가 생기는 이유

  • 매 요청마다 프로세스를 fork/exec하는 비용 발생합니다.
  • 메모리와 CPU 자원을 낭비합니다.
  • 대량의 동시 요청을 감당하기 어렵습니다.

 


 

자바 Servlet 예시 코드

import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
        
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().println(
            "<html>" +
            "<body>" +
            "<h1>Hello from Servlet!</h1>" +
            "</body>" +
            "</html>"
        );
    }
}
  • 이 서블릿은 브라우저에서 접속하면 "Hello from Servlet!"이라는 HTML을 출력합니다.

 

Servlet 동작 방식

  • 브라우저가 URL로 `/hello` 요청(request)을 보냅니다.
  • 요청을 받은 Servlet 컨테이너는 `HttpServletRequest`, `HttpServletResponse` 객체를 생성합니다.
  • `web.xml`이나 어노테이션(@WebServlet)으로 URL 매핑된 서블릿 클래스를 찾습니다.
  • 서버는 `HelloServlet` 인스턴스를 한번만 생성(Singleton Pattern)하고 재사용(새 스레드로 처리)합니다. 
  • `response.getWriter()`를 통해 HTML 응답을 생성한 뒤 `HttpServletResponse` 객체에 응답을 담아 Client(브라우저)에 반환합니다.
  • 응답이 완료되면 생성한 `HttpServletRequest`, `HttpServletResponse` 객체를 소멸합니다.

 


 

CGI vs Servlet 비교 요약

항목 CGI(Common GateWay Interface) Servlet (Java Servlet)
실행 방식 요청마다 새로운 프로세스 생성 한번 로드 후, 요청마다 새로운 스레드 실행
언어 Perl, Python, C 등 스크립트 언어 Java 기반
성능 낮음 (프로세스 생성 비용 큼) 높음 (경량 스레드 처리)
유지보수 파일 기반, 분산되어 있어 어려움 클래스 기반, 구조화되어 있어 용이

 


 

JSP (Java-Server Pages)

등장 이유 :

  • 서블릿의 단점을 일부 보완하고, HTML 내에서 자바 코드를 삽입해 보다 직관적으로 웹 페이지를 만들기 위해 1999년 등장했습니다.

 

개요 :

  • HTML 파일에 자바 코드를 삽입하는 방식 (`<% %>`문법 사용).
  • 최초 요청 시 서블릿으로 변환되어 실행되었습니다.
  • 표현과 로직을 분리하는 시도가 가능해졌지만 한계가 있었습니다.

 

단점 :

  • 자바 코드가 HTML에 섞여 코드가 지저분해졌습니다.
  • 로직과 뷰과 여전히 완전히 분리되지 않았습니다.
  • 대규모 프로젝트에선 코드 관리가 어렵습니다.

 

더보기

JSP 코드 예시

<%@ page contentType="text/html;charset=UTF-8" %>
<html>
<head>
    <title>회원 목록</title>
</head>
<body>
    <h1>회원 목록</h1>
    <ul>
        <%
            // 자바 로직이 직접 들어감 (데이터 조회)
            List<String> members = new ArrayList<>();
            members.add("홍길동");
            members.add("김철수");
            members.add("이영희");

            for(String member : members) {
        %>
            <li><%= member %></li>
        <%
            }
        %>
    </ul>
</body>
</html>
  • 로직(데이터 생성/처리)과 뷰(HTML 출력)이 한 파일에 섞여있다. (완벽하게 분리되지 않은 예시)

 

 

JSP 동작 방식 (서블릿과 연결)

  • 브라우저가 `/hello.jsp` 요청
  • JSP 엔진이 `.jsp` 파일을 `.java` 파일로 변환
  • 그 `.java` 파일을 컴파일하여 `.class` 파일로 생성
  • 서블릿으로 동작 → 결과 HTML을 클라이언트에 전송

 

 

Servlet과 JSP 구조 및 문제점

  • 위에서와 다르게 Servlet만을 사용한 경우, View를 위한 코드와 비지니스 로직을 처리하는 코드가 Servlet에 모두 존재하여 유지보수가 어려워집니다
  • 그래서 JSP를 사용하여 View를 분리하였지만 비지니스 로직의 일부가 JSP 파일 안에 존재합니다. 여전히 책임이 많아 유지보수가 어렵습니다.

 


 

Servlet, JSP 기반의 MVC 패턴 도입

개요 :

  • MVC 패턴이 도입되면서, UI, 비지니스 로직, 데이터를 분리하여 개발하는 방식이 등장했습니다.
  • Servlet은 주로 컨트롤러(비지니스 로직)로 사용되었고, JSP는 뷰(UI)를 담당하게 되었습니다.

 

장점 :

  • MVC 패턴은 웹 애플리케이션의 유지보수성과 확장성을 크게 향상시켰습니다.

 

단점 :

  • 개발자가 중복적으로 설정해줘야 하는 부분들이 다수 발생했습니다.

 

더보기

MVC 패턴 (Model-View-Controller Patttern)

Model-View-Controller의 약자로, 소프트웨어 디자인 패턴 중 하나입니다. 특히 웹 애플리케이션 구조 설계에서 자주 사용되며, 역할을 분리하여 유지보수성과 확장성을 높이는 것이 주 목적입니다.

 

 

핵심 내용

  • View가 분리된 이유의 핵심은 변경입니다.
  • 기획이 변하지 않는 이상 비즈니스 로직과 View의 수정 원인은 별개로 발생합니다.
    • 화면 구성에 수정이 발생하면 View만 변경
    • 요구사항에 수정이 발생하는 경우 비즈니스 로직 변경
  • 즉, 서로 연관이 없는 코드끼리 함께 존재할 필요가 없습니다. → 완전히 분리하자. (역할 분리)

 

 

MVC 패턴 구조

 

 

MVC 구성요소

1. Model (모델) : 애플리케이션의 데이터와 비즈니스 로직을 담당하는 객체입니다.

  • 데이터베이스와 직접 연동하거나 데이터를 처리하는 역할
  • 예: 회원 정보, 게시글, 주문 정보 등

2. View (뷰) : 사용자에게 출력(화면)을 보여주는 역할입니다.

  • HTML, JSP, Thymeleaf, React, Vue 등 다양한 템플릿/프론트엔드 기술을 사용할 수 있습니다.
  • 사용자 인터페이스(UI)를 구성합니다.
  • 로직 없이 표현만 담당해야합니다.

3. Controller (컨트롤러) : 사용자의 요청을 받고, 모델과 뷰를 연결해주는 중재자 역할의 객체입니다.

  • Controller는 Servlet에 해당됩니다.
  • 사용자의 입력(HTTP 요청)을 받고, 파라미터 검증을 한 후, 비즈니스 로직을 실행한 다음, 
  • 비즈니스 로직을 실행합니다.
  • View에 전달할 결과를 조회하여 Model 객체에 임시로 저장합니다.
  • 예 : URL 요청을 받아 어떤 데이터를 조회하고 어떤 화면을 보여줄지 결정합니다.

 

 


 

MVC 프레임워크의 등장 : Struts, Spring MVC (2000~2010)

등장 이유 :

  • 웹 애플리케이션의 규모가 커지고 복잡해지면서, 명확한 구조와 분리된 책임이 필요해졌습니다.
  • JSP/Servlet만으로는 생산성과 유지보수성이 떨어집니다.

 

개요 :

  • Struts (2000년 초반) : 최초의 대중적인 자바 MVC 프레임워크
  • Spring MVC : Spring Framework의 일부분으로, 보다 유연하고 확장성이 뛰어난 구조를 제공합니다
  • MVC(Model-View-Controller) 패턴을 기반으로 합니다.

단점 :

  • 초기 설정이 복잡했습니다 (Spring 3 이전까지)
  • 개발 속도가 느릴 수 있습니다 (설정 및 구조 이해 필요)

 

더보기

웹 서버 설정

  • 보통은 Tomcat 같은 서버를 따로 설치하고, 설정 파일(`web.xml`)도 만들어야 합니다.

 

스프링 설정 파일 작성 (web.xml)

<!-- web.xml에서 서블릿 등록 -->
<servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>
        <param-name>config</param-name>
        <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

<!-- struts-config.xml -->
<action-mappings>
    <action path="/login" 
            type="com.example.LoginAction" 
            name="loginForm" 
            scope="request" 
            input="/login.jsp">
        <forward name="success" path="/home.jsp"/>
        <forward name="failure" path="/login.jsp"/>
    </action>
</action-mappings>
  • 이런 식으로 여러 개의 XML 파일에서 각각의 요청 경로, 액션 클래스(비즈니스 로직 처리 클래스), 뷰 페이지 등을 일일이 매핑해줘야 했습니다.
  • 페이지가 많아질수록 설정 파일도 덩달아 커지고 복잡해졌습니다.

 

라이브러리 의존성 관리

  • 어떤 라이브러리가 필요한지 직접 찾아서 pom.xml이나 build.gradle에 하나하나 추가합니다.
  • 웹 개발에 필요한 모든 것들을 직접 찾아서 직접 버전을 맞춰 추가해야했습니다. (엄청 피로)

 

프로젝트 구조 관리

  • 여러 설정 파일, 자원 위치를 일일이 맞춰야 했습니다.

 


 

Annotaion 기반의 Spring MVC (2007~현재)

개요 :

  • Annotaion을 통해 애플리케이션 설정의 복잡함을 줄여줍니다.

 

장점 :

  • 더 직관적이고 간결한 방식으로 웹 애플리케이션을 개발할 수 있게 되었습니다.

 

더보기

1. 설정 방식이 XML에서 자바(Annotaion) 기반으로 대폭 개선

@Controller
public class HelloController {

    @RequestMapping("/hello")
    public String sayHello(Model model) {
        model.addAttribute("message", "Hello Spring 3+");
        return "hello";  // 뷰 이름 (ex. hello.jsp)
    }
}
  • 기존에 XML에 모든 URL 매핑, 컨트롤러, 뷰 리졸버 등을 일일이 작성하던 방식에서 `@Controller`, `@RequestMapping` 같은 어노테이션(Annotation)을 활용코드 내에 직접 선언할 수 있게 되었습니다.
  • 설정파일이 대폭 줄고, 코드와 설정이 가까워져서 유지보수 쉬워졌습니다.

 

 

2. `@EnableWebeMvc`와 `WebMvcConfigurer`로 기본 설정을 간편하게 처리

@Configuration
@EnableWebMvc
@ComponentScan("com.example.controller")
public class WebConfig implements WebMvcConfigurer {
    // 필요한 설정만 추가로 작성
}
  • `@EnableWebMvc` : 필요한 컴포넌트를 자동으로 등록할 수 있습니다.
  • `WebMvcConfigurer` : 여러 메서드를 오버라이드해서(재정의해서) 기본 동작에 추가하거나 바꿀 수 있습니다.

컴포넌트란 : 독립적인 기능을 가진 부품이나 모듈

@Component
public class MyService {
    // 서비스 역할을 하는 컴포넌트
}
  • 컴포넌트로 표시된 클래스들은 스프링이 자동으로 찾아서 필요할 때 만들어주고 연결해 줍니다.

 

 

3. `@RestController` 등장으로 REST API 개발이 간편

@RestController
public class ApiController {

    @GetMapping("/api/data")
    public Map<String, String> getData() {
        return Collections.singletonMap("message", "Hello REST");
    }
}
  • 기존에 JSP 등 뷰를 반환하는 컨트롤러와 별개로  JSON, XML 등의 데이터를 직접 반환하는 RESTful API 개발도 쉽게 가능해졌습니다.

 

 

4. 템플릿 엔진 (Thymeleaf, FreeMaker 등) 쉽게 연동 가능

  • JSP 외에 다양한 뷰 기술을 쉽게 적용할 수 있어서 자유도가 높아졌습니다.

 

 


 

Spring Boot의 등장 (2014~현재)

개요 :

Spring 프레임워크를 보다 쉽게 사용하도록 만든 도구로, 설정과 복잡한 초기 설정 작업을 자동화했습니다.

내장 Tomcat을 가지고 있습니다.

 

장점 :

개발자들이 빠르게 애플리케이션을 개발할 수 있도록 도와줍니다.

 

더보기

내장 서버 제공

  • Tomcat, Jetty 등 서버를 애플리케이션 안에 포함해서, 따로 서버 설치/설정 없이 java -jar로 바로 실행 가능.

 

자동 설정(Auto-Configuration)

  • 프로젝트에 추가한 라이브러리를 분석해서, 필요한 설정을 자동으로 만들어줌
  • 예: 데이터베이스 라이브러리 있으면 자동으로 DB 연결 설정
  • 웹 라이브러리 있으면 웹 서버 설정 자동 완료

 

스타터(Starter) 의존성 제공

  • 여러 관련 라이브러리를 묶은 패키지를 제공해, 필요한 기능을 쉽게 추가 가능 (spring-boot-starter-web 등)
  • 모든 스타터 버전을 호환되게 미리 정리해 두 었기 때문에 일일이 버전을 맞추거나 충돌을 걱정할 필요가 없습니다.

 

간단한 실행

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication  // Spring Boot 자동 설정 시작 어노테이션
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);  // 내장 서버 실행
    }

    @RestController  // REST API용 컨트롤러
    class HelloController {

        @GetMapping("/hello")
        public String hello() {
            return "Hello, Spring Boot!";
        }
    }
}
  • 복잡한 설정 없이도 몇 줄 코드로 애플리케이션 시작 가능합니다.
  • 빌드 후 `java -jar yourapp.jar`로 실행하면 내장 톰캣 서버가 켜지고 웹 브라우저에서 `http://locathost:8080/hello`에 접속하면 "Hello, Spring Boot!" 메시지 확인 가능합니다.

'JAVA' 카테고리의 다른 글

[Java] Lombok 라이브러리  (0) 2025.05.10
[Java] Optional  (0) 2025.05.04
[Java] 동등성과 동일성  (0) 2025.05.04
[Java] Enum  (0) 2025.05.04
[Java] Lv_4 도서관 프로젝트  (0) 2025.05.02