본문 바로가기
Everyday Study

2024.10.09(수) { 커넥터, @Controller 랑 @RestController, 서버에서 뷰(HTML)를 제공하지 않고 데이터만 제공하는 방식, 컨트롤러 메서드를 만들 때 헤매지 않고 참고할 수 있는 부분 }

by xogns93 2024. 10. 9.

Apache Tomcat은 여러 가지 커넥터를 제공하며, 그 중에서 주요한 커넥터 3가지는 HTTP/1.1 (Coyote), HTTPS, AJP입니다. 또한, NIO, NIO2, APR과 같은 다양한 I/O 방식을 지원하는 커넥터들도 존재합니다. 아래에서 각 커넥터를 간단히 설명드리겠습니다.

1. HTTP/1.1 (Coyote):

  • Coyote는 Tomcat에서 기본적으로 제공하는 HTTP/1.1 커넥터입니다.
  • HTTP 요청과 응답을 처리하며, 대부분의 웹 트래픽을 처리할 때 사용됩니다.
  • 클라이언트와 서버 간의 기본적인 HTTP 통신을 담당합니다.

2. HTTPS:

  • HTTP over SSL/TLS를 지원하는 커넥터로, 보안이 필요한 웹 트래픽을 처리할 때 사용됩니다.
  • HTTPS 커넥터는 기본적인 Coyote 커넥터의 확장으로, SSL/TLS 암호화를 적용해 클라이언트와 서버 간의 안전한 통신을 보장합니다.

3. AJP (Apache JServ Protocol):

  • **AJP (Apache JServ Protocol)**는 Tomcat과 다른 웹 서버(예: Apache HTTP Server) 사이에서 바이너리 프로토콜로 트래픽을 전달하는 데 사용됩니다.
  • 로드 밸런싱이나 리버스 프록시 설정에서 자주 사용되며, Apache HTTP Server와 같은 웹 서버가 HTTP 요청을 수신하고 이를 Tomcat으로 전달할 때 사용됩니다.

추가적으로 제공되는 I/O 방식 커넥터:

  • NIO (Non-blocking I/O): NIO 커넥터는 자바의 Non-blocking I/O를 사용해 높은 성능과 확장성을 제공합니다. 대규모 동시 연결을 효율적으로 처리할 수 있는 커넥터입니다.
  • NIO2: NIO2는 Java 7에서 추가된 Asynchronous I/O 기능을 사용하여, 더 나은 성능과 자원을 효율적으로 사용할 수 있는 비동기적인 방식의 커넥터입니다.
  • APR (Apache Portable Runtime): APR 커넥터는 네이티브 라이브러리를 사용하여 성능을 극대화하는 커넥터입니다. Tomcat에서 C와 같은 저수준 네이티브 코드 기반으로 성능 향상을 지원합니다.

요약:

  • 기본 커넥터: HTTP/1.1 (Coyote), HTTPS, AJP
  • 추가 I/O 커넥터: NIO, NIO2, APR

각 커넥터는 Tomcat에서 특정 요구사항(성능, 보안, 확장성 등)에 따라 적절히 선택하여 사용할 수 있습니다.


@Controller@RestController는 모두 스프링 프레임워크에서 사용되는 애노테이션으로, HTTP 요청을 처리하고, 그에 대한 응답을 반환하는 컨트롤러 클래스를 나타냅니다. 이 두 애노테이션은 주로 스프링 MVC와 REST API를 구현할 때 사용됩니다. 이 두 애노테이션의 차이점과 핸들러 메서드에 대해 설명하겠습니다.

1. @Controller

개념

  • @Controller전통적인 스프링 MVC 웹 애플리케이션에서 사용되는 애노테이션입니다. 주로 HTML 페이지 또는 JSP와 같은 뷰를 반환하는데 사용됩니다.
  • 컨트롤러 클래스에 @Controller 애노테이션을 붙이면, 이 클래스의 메서드가 HTTP 요청을 처리하는 핸들러 메서드(Handler Method)로 동작하게 됩니다.
  • 뷰 리졸버(View Resolver)를 통해 반환된 결과를 특정한 뷰(예: JSP, Thymeleaf)로 렌더링하여 사용자에게 반환합니다.

사용 예시

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("/greet")
public class GreetController {

    @GetMapping("/hello")
    public ModelAndView sayHello() {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName("hello"); // 'hello.jsp'와 같은 뷰를 반환
        modelAndView.addObject("message", "Hello, Spring MVC!");

        return modelAndView; // 뷰 이름과 데이터를 반환
    }
}

특징

  • @Controller를 사용하는 핸들러 메서드는 뷰 이름을 반환하며, 이 뷰 이름에 해당하는 템플릿 파일이 렌더링됩니다.
  • ModelAndView 객체를 통해 모델(데이터)과 뷰(화면)를 함께 반환할 수 있습니다.
  • 데이터를 JSON이나 XML과 같은 형태로 반환하려면, 메서드에 @ResponseBody 애노테이션을 추가해야 합니다. 즉, 기본적으로는 뷰를 반환하는 것이 목적입니다.

뷰 리졸버 동작 과정

  1. @Controller가 HTTP 요청을 받아 메서드를 실행합니다.
  2. 메서드가 뷰 이름을 반환하면, 뷰 리졸버(View Resolver)가 해당 뷰 이름에 대응하는 JSP, Thymeleaf 템플릿 등을 찾아 렌더링합니다.
  3. 클라이언트에게 HTML 또는 렌더링된 웹 페이지가 반환됩니다.

2. @RestController

개념

  • @RestControllerREST API 개발을 위한 컨트롤러에 사용됩니다. @Controller와 달리 JSON 또는 XML 등의 데이터를 반환하는 것이 주목적입니다.
  • @RestController@Controller@ResponseBody의 결합체로, 모든 핸들러 메서드가 자동으로 JSON 형식으로 데이터를 직렬화하여 반환합니다.

사용 예시

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api/greet")
public class GreetRestController {

    @GetMapping("/hello")
    public String sayHello() {
        return "Hello, REST API!";
    }
}

특징

  • @RestController는 데이터를 반환할 때, 메서드에 따로 @ResponseBody 애노테이션을 붙일 필요가 없습니다. 모든 메서드는 기본적으로 JSON 형식으로 데이터를 반환합니다.
  • 뷰 리졸버가 동작하지 않으며, 반환 값은 뷰가 아니라 데이터(주로 JSON)입니다.
  • REST API 개발에서 주로 사용되며, 클라이언트에게 HTML 페이지가 아닌 데이터(JSON, XML)를 제공하는 데 적합합니다.

3. @Controller@RestController의 차이점

특성 @Controller @RestController
주된 사용 용도 전통적인 웹 애플리케이션 (뷰 반환) REST API (데이터 반환)
데이터 반환 방식 뷰 이름을 반환하여 HTML 등으로 렌더링됨 JSON 또는 XML 데이터 반환
뷰 리졸버 뷰 리졸버를 통해 JSP, HTML 등 반환 뷰 리졸버를 사용하지 않음
애노테이션 구성 @Controller (뷰 처리) + @ResponseBody @RestController (자동으로 데이터 처리)
주로 사용하는 리턴 타입 ModelAndView 또는 뷰 이름 객체(데이터 모델) 또는 문자열

4. 핸들러 메서드(엔드포인트 메서드)

핸들러 메서드는 HTTP 요청을 처리하고, 그 결과를 반환하는 메서드입니다. 핸들러 메서드는 주로 @RequestMapping, @GetMapping, @PostMapping 등의 애노테이션으로 매핑되어 특정 URL이나 HTTP 메서드에 대응됩니다.

핸들러 메서드의 기본 구조

  1. 매핑: 특정 URL 경로나 HTTP 메서드(GET, POST 등)에 매핑됩니다.
  2. 파라미터: 요청에 포함된 파라미터, 헤더 등을 받아 처리할 수 있습니다.
  3. 응답 반환: 핸들러 메서드는 처리 결과를 뷰(HTML)로 반환하거나, 데이터를 JSON 또는 XML 형식으로 반환할 수 있습니다.

예시: @RestController에서의 핸들러 메서드

@RestController
@RequestMapping("/api/users")
public class UserController {

    // GET 요청을 처리하는 핸들러 메서드
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return new User(id, "John Doe"); // JSON 형식으로 반환
    }

    // POST 요청을 처리하는 핸들러 메서드
    @PostMapping
    public User createUser(@RequestBody User user) {
        // 사용자 생성 로직
        return user; // 생성된 사용자를 JSON 형식으로 반환
    }
}

예시: @Controller에서의 핸들러 메서드

@Controller
@RequestMapping("/users")
public class UserController {

    @GetMapping("/{id}")
    public ModelAndView getUser(@PathVariable Long id) {
        ModelAndView modelAndView = new ModelAndView("userProfile"); // 뷰 이름 반환
        modelAndView.addObject("user", new User(id, "John Doe")); // 모델에 데이터 추가
        return modelAndView; // JSP나 HTML 파일로 렌더링
    }
}

요약

  • @Controller는 웹 애플리케이션에서 HTML과 같은 뷰를 반환하기 위해 사용되고, 주로 전통적인 웹 애플리케이션에서 사용됩니다.
  • @RestControllerJSON 또는 XML 형식으로 데이터를 반환하는 REST API 컨트롤러에서 사용됩니다. @ResponseBody를 기본적으로 포함하고 있어 데이터를 직렬화하여 클라이언트에 전달합니다.
  • 핸들러 메서드는 특정 요청을 처리하고 응답을 반환하는 메서드로, 스프링에서 HTTP 요청을 처리하는 핵심적인 기능입니다.

이 말은 웹 서버가 전통적인 방식으로 웹 페이지(HTML, CSS, JavaScript 등)를 제공하는 역할을 하지 않고, 데이터만 클라이언트에게 제공하는 역할을 한다는 의미입니다. 이를 통해, 웹 페이지 렌더링을 서버에서 수행하지 않고, 클라이언트가 직접 데이터를 받아 웹 페이지를 구성하게 됩니다. 즉, 서버는 API 서버로 동작하여 JSON 또는 XML 형식의 데이터만을 반환하고, 뷰(View)를 서버에서 관리하지 않는다는 의미입니다.

웹 서버와 API 서버의 차이

  1. 전통적인 웹 서버:
    • 서버에서 HTML 페이지를 동적으로 생성하여 클라이언트에게 전송합니다.
    • 뷰 템플릿 엔진(Thymeleaf, JSP 등)을 통해 서버에서 HTML과 같은 뷰를 렌더링합니다.
    • 클라이언트는 서버에서 받은 HTML 페이지를 브라우저에서 표시합니다.
  2. API 서버:
    • 서버는 웹 페이지(HTML) 대신 데이터만을 반환합니다. 이 데이터는 주로 JSON 또는 XML 형식으로 제공됩니다.
    • 클라이언트(주로 프론트엔드 애플리케이션)는 서버로부터 받은 데이터를 이용해 화면을 구성합니다.
    • 웹 페이지는 클라이언트 쪽에서 JavaScript 프레임워크(예: React, Angular, Vue.js) 등을 이용해 렌더링합니다.
    • 즉, 서버는 클라이언트의 요청에 대해 데이터만 제공하고, 웹 페이지의 렌더링은 클라이언트 측에서 이루어집니다.

뷰와 관련된 개념들이 필요 없는 이유

  • View Name: 전통적인 방식에서 서버는 요청에 따라 적절한 뷰(HTML 페이지) 이름을 반환합니다. 그러나 API 서버에서는 뷰를 제공하지 않기 때문에, 더 이상 뷰 이름을 반환할 필요가 없습니다.
  • View Resolver: 뷰 리졸버는 컨트롤러가 반환하는 뷰 이름을 보고, 그에 맞는 템플릿 파일(JSP, Thymeleaf 등)을 찾아 렌더링하는 역할을 합니다. API 서버에서는 HTML을 렌더링할 필요가 없기 때문에, 뷰 리졸버도 필요하지 않습니다.
  • Model: 전통적인 방식에서는 서버에서 뷰에 데이터를 전달하기 위해 Model 객체를 사용합니다. 하지만 API 서버는 데이터를 클라이언트에 JSON 형식으로 직접 전달하므로, Model 객체도 필요하지 않습니다.

API 서버의 동작 방식

API 서버는 다음과 같은 방식으로 동작합니다.

  1. 클라이언트 요청: 클라이언트(프론트엔드)는 특정 데이터를 요청합니다. 예를 들어, 사용자의 목록이나 특정 게시물의 정보를 요청할 수 있습니다.
  2. 서버 응답: 서버는 클라이언트의 요청을 처리하고, HTML 뷰를 반환하는 대신 JSON 형식으로 데이터를 응답합니다.
  3. 클라이언트 데이터 처리: 클라이언트는 서버에서 받은 데이터를 기반으로 화면을 구성하거나, 추가 작업을 수행합니다. 화면 구성은 클라이언트 측에서 JavaScriptJavaScript 프레임워크를 통해 이루어집니다.

예시: API 서버

아래는 스프링에서 API 서버로 동작하는 컨트롤러의 예시입니다. 데이터를 JSON으로 반환하며, 뷰를 사용하지 않습니다.

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController // @Controller + @ResponseBody, 뷰 없이 데이터만 반환
@RequestMapping("/api/users")
public class UserController {

    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        // 사용자 정보를 JSON으로 반환
        return userService.getUserById(id);
    }
}

이 컨트롤러는 요청된 사용자 ID에 대한 데이터를 JSON으로 반환합니다. 뷰 이름이나 뷰 리졸버는 사용되지 않으며, 오직 데이터만 클라이언트에게 제공됩니다.

클라이언트 측의 역할

클라이언트는 서버에서 데이터를 받아 화면을 구성하는 역할을 합니다. 프론트엔드 프레임워크나 라이브러리를 사용하여 데이터를 표시할 수 있습니다. 예를 들어, React나 Vue.js와 같은 도구를 사용하여 서버에서 받은 데이터를 동적으로 웹 페이지에 렌더링할 수 있습니다.

// 클라이언트 측 예시 (JavaScript로 서버 데이터 요청 및 처리)
fetch('/api/users/1')
  .then(response => response.json())
  .then(data => {
    console.log(data); // 서버에서 받은 사용자 데이터를 처리
    // 화면에 데이터를 동적으로 추가
  });

요약

  • 서버에서 뷰(HTML)를 제공하지 않고 데이터만 제공하는 방식은 주로 RESTful API 서버에서 사용됩니다.
  • View Name, View Resolver, Model 등은 전통적인 서버 렌더링 방식에서 사용되지만, API 서버에서는 필요하지 않습니다.
  • 클라이언트는 서버에서 받은 데이터(JSON)를 이용해 화면을 구성하며, 웹 페이지의 렌더링은 클라이언트 측에서 이루어집니다.
  • 이는 웹 애플리케이션을 백엔드(API 서버)프론트엔드(클라이언트)로 분리하여 더 유연하게 설계하는 현대적인 웹 애플리케이션 구조입니다.

컨트롤러 메서드를 만들 때 헤매지 않고 참고할 수 있는 부분은 바로 스프링의 애노테이션핸들러 메서드의 매핑 방식입니다. 특히, 스프링에서 제공하는 주요 애노테이션들을 잘 이해하면 컨트롤러 메서드를 쉽게 만들 수 있습니다.

컨트롤러 메서드 작성을 위한 핵심 애노테이션과 참고해야 할 사항들을 아래에서 정리해 보겠습니다.

1. 컨트롤러 애노테이션

컨트롤러 메서드를 만들 때 가장 중요한 애노테이션들은 주로 다음과 같습니다:

1) @Controller 또는 @RestController

  • @Controller: 주로 HTML 뷰(예: JSP, Thymeleaf)를 반환할 때 사용됩니다.
  • @RestController: 주로 JSON 또는 XML과 같은 데이터를 반환할 때 사용되며, @Controller + @ResponseBody의 역할을 합니다.

2) 요청 매핑 애노테이션

요청이 들어왔을 때 컨트롤러 메서드와 URL을 매핑하기 위해 사용하는 애노테이션입니다. 주로 HTTP 메서드(GET, POST, PUT, DELETE 등)와 경로를 정의합니다.

  • @RequestMapping: 특정 URL 및 HTTP 메서드에 대해 매핑을 설정합니다. (GET, POST, PUT, DELETE를 모두 처리할 수 있음)
  • @GetMapping, @PostMapping, @PutMapping, @DeleteMapping: 각각 GET, POST, PUT, DELETE 요청에 대해 쉽게 매핑할 수 있도록 제공되는 단축형 애노테이션입니다.

3) 요청 데이터 매핑 애노테이션

요청 파라미터나 경로 변수를 컨트롤러 메서드의 매개변수로 바인딩할 때 사용하는 애노테이션입니다.

  • @RequestParam: URL 쿼리 파라미터를 매개변수로 받습니다.
  • @PathVariable: URL 경로의 변수를 메서드 매개변수로 받습니다.
  • @RequestBody: 요청 본문 데이터를 JSON, XML 등의 형태로 받아 객체로 변환해 매개변수로 받습니다.

2. 가장 많이 사용하는 컨트롤러 메서드의 구조

컨트롤러 메서드를 작성할 때는 주로 다음과 같은 구조를 사용합니다.

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@Controller
public class ExampleController {

    // GET 요청 처리
    @GetMapping("/greet")
    public String greet(@RequestParam String name, Model model) {
        model.addAttribute("name", name);
        return "greeting"; // 뷰 이름 반환
    }

    // POST 요청 처리
    @PostMapping("/submit")
    public String submitForm(@RequestParam String data, Model model) {
        model.addAttribute("data", data);
        return "result"; // 뷰 이름 반환
    }
}
  • @GetMapping: 특정 URL 경로에 대한 GET 요청을 처리합니다.
  • @RequestParam: 쿼리 파라미터(예: ?name=John)를 메서드 매개변수로 전달합니다.
  • Model: 데이터를 뷰에 전달하기 위해 사용합니다.
  • return "greeting": greeting.html과 같은 뷰 템플릿 이름을 반환합니다.

3. JSON 데이터를 처리하는 메서드 (API 서버)

import org.springframework.web.bind.annotation.*;

@RestController
public class ApiController {

    // GET 요청에서 JSON 데이터 반환
    @GetMapping("/api/user/{id}")
    public User getUser(@PathVariable Long id) {
        return new User(id, "John Doe", "john@example.com"); // JSON 반환
    }

    // POST 요청에서 JSON 데이터를 받아 처리
    @PostMapping("/api/user")
    public User createUser(@RequestBody User user) {
        // 요청으로 받은 user 데이터를 처리
        return user;
    }
}
  • @RestController: JSON 또는 XML 데이터를 반환하는 API 컨트롤러를 정의합니다.
  • @RequestBody: 요청 본문에서 JSON 데이터를 객체로 변환해 매개변수로 받습니다.
  • @PathVariable: URL 경로에 포함된 변수를 메서드 매개변수로 받습니다.

4. 레퍼런스 참고 자료

스프링에서 제공하는 공식 문서애노테이션 관련 가이드를 보면 컨트롤러 메서드를 쉽게 작성할 수 있습니다. 스프링 공식 문서에서는 각 애노테이션의 사용법과 메서드 작성 예시가 잘 정리되어 있습니다.

5. 요약

컨트롤러 메서드를 쉽게 작성하려면 다음 사항을 참고하면 됩니다:

  • 애노테이션의 역할: @RequestMapping, @GetMapping, @PostMapping, @RequestParam, @RequestBody, @PathVariable 등 애노테이션을 사용하여 요청을 컨트롤러 메서드와 매핑하고, 요청 데이터를 처리합니다.
  • 반환 타입: 뷰 이름을 반환할지(JSON 데이터인지) 결정하는 @Controller 또는 @RestController 애노테이션 사용.
  • 스프링 공식 문서: 스프링 MVC 컨트롤러를 구현할 때 공식 문서가 매우 유용한 자료입니다. 각 애노테이션과 메서드의 사용법이 잘 설명되어 있습니다.

위 애노테이션들과 관련 기능을 이해하고 사용하면, 컨트롤러 메서드를 쉽게 작성할 수 있습니다.