# **Spring Boot MVC: 컨트롤러와 요청 처리** Spring Boot의 핵심 기능 중 하나는 **MVC(Model-View-Controller) 패턴을 사용한 웹 요청 처리**입니다. 이 글에서는 **Spring Boot에서 컨트롤러가 어떻게 요청을 처리하는지**, 그리고 실무에서 **자주 사용하는 컨트롤러 관련 기능**을 예제와 함께 설명합니다. --- ## **1. 컨트롤러란?** 컨트롤러(Controller)는 **클라이언트의 요청을 받아서 비즈니스 로직을 수행하고, 응답을 반환하는 역할**을 합니다. Spring Boot에서는 `@RestController` 또는 `@Controller` 어노테이션을 사용하여 컨트롤러를 정의합니다. --- ## **2. 기본 컨트롤러 작성하기** Spring Boot에서는 `@RestController`를 사용하면 JSON 형태로 응답을 반환할 수 있습니다. ### **📌 기본 컨트롤러 예제** ```java @RestController @RequestMapping("/api") public class HelloController { @GetMapping("/hello") public String sayHello() { return "Hello, Spring Boot!"; } } ``` #### **📌 실행 결과 (`http://localhost:8080/api/hello` 요청)** ```json Hello, Spring Boot! ``` **설명:** - `@RestController` → REST API를 위한 컨트롤러를 정의. - `@RequestMapping("/api")` → 모든 경로가 `/api`로 시작하도록 설정. - `@GetMapping("/hello")` → `/api/hello`로 GET 요청이 들어오면 `"Hello, Spring Boot!"` 반환. --- ## **3. 요청 매개변수 처리** 클라이언트가 **쿼리 파라미터** 또는 **URL 경로 변수**를 전달하면, 이를 컨트롤러에서 처리할 수 있습니다. ### **📌 `@RequestParam` 사용 (쿼리 파라미터)** ```java @RestController @RequestMapping("/api") public class GreetingController { @GetMapping("/greet") public String greet(@RequestParam String name) { return "Hello, " + name + "!"; } } ``` #### **📌 실행 결과 (`http://localhost:8080/api/greet?name=John` 요청)** ```json Hello, John! ``` **설명:** - `@RequestParam`을 사용하면 **쿼리 파라미터에서 값을 가져올 수 있음**. - 예제에서는 `name` 값을 받아 `"Hello, John!"`을 반환. --- ### **📌 `@PathVariable` 사용 (URL 경로 변수)** ```java @RestController @RequestMapping("/api") public class UserController { @GetMapping("/user/{id}") public String getUser(@PathVariable int id) { return "User ID: " + id; } } ``` #### **📌 실행 결과 (`http://localhost:8080/api/user/5` 요청)** ```json User ID: 5 ``` **설명:** - `@PathVariable`을 사용하면 **URL 경로에서 변수를 추출**할 수 있음. - 예제에서는 `/user/5` 요청 시, `id=5`로 인식하여 `"User ID: 5"` 반환. --- ## **4. 요청 본문 처리 (POST 요청)** 클라이언트가 **JSON 데이터를 요청 본문(body)에 담아 전송**하면, 이를 컨트롤러에서 처리할 수 있습니다. ### **📌 `@RequestBody` 사용** ```java @RestController @RequestMapping("/api") public class ProductController { @PostMapping("/product") public String createProduct(@RequestBody Product product) { return "Product created: " + product.getName(); } } class Product { private String name; private double price; // 기본 생성자 필요 (JSON 역직렬화) public Product() {} public String getName() { return name; } public double getPrice() { return price; } } ``` #### **📌 실행 결과 (`POST /api/product` 요청)** ##### **요청 본문(JSON)** ```json { "name": "Laptop", "price": 1200.00 } ``` ##### **응답** ```json Product created: Laptop ``` **설명:** - `@RequestBody`를 사용하면 **JSON 데이터를 Java 객체로 변환하여 받을 수 있음**. - 클라이언트가 `{ "name": "Laptop", "price": 1200.00 }`을 전송하면, 이를 `Product` 객체로 매핑. - `"Product created: Laptop"`을 반환. --- ## **5. 응답 데이터 처리** Spring Boot에서는 다양한 방식으로 응답을 반환할 수 있습니다. ### **📌 `ResponseEntity`를 사용한 응답 처리** ```java @RestController @RequestMapping("/api") public class ResponseController { @GetMapping("/status") public ResponseEntity getStatus() { return ResponseEntity.status(HttpStatus.OK) .body("Everything is fine!"); } } ``` #### **📌 실행 결과 (`GET /api/status` 요청)** ```json Everything is fine! ``` **설명:** - `ResponseEntity`를 사용하면 **HTTP 상태 코드와 응답 데이터를 함께 설정 가능**. - `HttpStatus.OK` → 200 응답 코드 설정. --- ## **6. 요청 및 응답 헤더 처리** ### **📌 `@RequestHeader` 사용 (요청 헤더 읽기)** ```java @RestController @RequestMapping("/api") public class HeaderController { @GetMapping("/header") public String getHeader(@RequestHeader("User-Agent") String userAgent) { return "Your User-Agent: " + userAgent; } } ``` #### **📌 실행 결과 (`GET /api/header` 요청)** ```json Your User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ``` **설명:** - `@RequestHeader("User-Agent")`를 사용하여 요청 헤더에서 **User-Agent 값 추출**. --- ## **7. 예외 처리 (`@ExceptionHandler`)** ### **📌 컨트롤러에서 예외 처리하기** ```java @RestController @RequestMapping("/api") public class ExceptionController { @GetMapping("/error") public String throwError() { throw new RuntimeException("Something went wrong!"); } @ExceptionHandler(RuntimeException.class) public ResponseEntity handleRuntimeException(RuntimeException e) { return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body("Error: " + e.getMessage()); } } ``` #### **📌 실행 결과 (`GET /api/error` 요청)** ```json Error: Something went wrong! ``` **설명:** - `@ExceptionHandler(RuntimeException.class)`을 사용하여 **컨트롤러 내에서 예외 처리**. --- ## **8. 정리** | 기능 | 어노테이션 | 설명 | |------|----------|------| | **기본 컨트롤러** | `@RestController` | REST API 컨트롤러 정의 | | **GET 요청 처리** | `@GetMapping` | HTTP GET 요청 매핑 | | **POST 요청 처리** | `@PostMapping` | HTTP POST 요청 매핑 | | **쿼리 파라미터** | `@RequestParam` | URL 쿼리 매개변수 받기 | | **URL 경로 변수** | `@PathVariable` | URL 경로에서 값 추출 | | **JSON 요청 본문** | `@RequestBody` | 요청 본문을 객체로 매핑 | | **요청 헤더 처리** | `@RequestHeader` | 요청 헤더 값을 읽기 | | **응답 처리** | `ResponseEntity` | 상태 코드와 함께 응답 반환 | | **예외 처리** | `@ExceptionHandler` | 예외 발생 시 응답 처리 | Spring Boot의 컨트롤러는 **간결하면서도 강력한 기능**을 제공합니다. 실무에서는 **REST API 개발 시 `@RestController`, 요청 처리 시 `@RequestParam`, `@RequestBody`, 예외 처리 시 `@ExceptionHandler`** 등을 적극 활용하면 좋습니다! ------ # **Spring Boot MVC에서 컨트롤러와 요청 처리** Spring Boot MVC에서 컨트롤러는 **클라이언트 요청을 받아 적절한 응답을 반환하는 역할**을 합니다. 컨트롤러를 정의하려면 `@Controller` 또는 `@RestController`를 사용하며, 요청을 처리하는 메서드는 `@RequestMapping`, `@GetMapping`, `@PostMapping` 등의 어노테이션을 사용하여 HTTP 요청을 매핑할 수 있습니다. --- ## **1. 컨트롤러 기본 개념** 컨트롤러는 **MVC(Model-View-Controller) 패턴에서 "C(Controller)" 역할**을 하며, 클라이언트의 요청을 받아서 처리한 후 적절한 뷰(HTML) 또는 데이터를 응답으로 반환합니다. ### **📌 컨트롤러를 정의하는 어노테이션** | 어노테이션 | 설명 | |------------|----------------------------------| | `@Controller` | 뷰(HTML)를 반환하는 컨트롤러 | | `@RestController` | JSON, XML 데이터를 반환하는 컨트롤러 | | `@RequestMapping` | HTTP 요청을 특정 메서드에 매핑 | | `@GetMapping` | GET 요청을 처리 | | `@PostMapping` | POST 요청을 처리 | | `@PutMapping` | PUT 요청을 처리 | | `@DeleteMapping` | DELETE 요청을 처리 | --- ## **2. 기본 컨트롤러 예제** ```java import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @Controller public class HomeController { @GetMapping("/") public String home(Model model) { model.addAttribute("message", "Hello, Spring Boot!"); return "home"; // home.html 템플릿을 반환 } } ``` ### **🛠️ 코드 설명** - `@Controller` → **이 클래스를 컨트롤러로 선언** - `@GetMapping("/")` → **루트 경로(`/`)로 GET 요청이 들어오면 `home()` 메서드 실행** - `Model` 객체를 이용해 `"message"` 데이터를 뷰로 전달 - `return "home"` → **`home.html` 템플릿을 사용하여 응답 반환** --- ## **3. `@RestController`를 사용한 JSON 응답 컨트롤러** ```java import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class ApiController { @GetMapping("/api/hello") public String hello(@RequestParam(defaultValue = "Guest") String name) { return "Hello, " + name + "!"; } } ``` ### **🛠️ 코드 설명** - `@RestController` → **뷰가 아니라 JSON 데이터 응답을 위한 컨트롤러** - `@GetMapping("/api/hello")` → **`/api/hello`로 GET 요청이 들어오면 `hello()` 실행** - `@RequestParam("name")` → **쿼리 파라미터(name)를 받아서 사용** - `return "Hello, " + name + "!";` → **단순한 문자열을 응답으로 반환** ### **✅ 실행 예시** 요청: ``` GET http://localhost:8080/api/hello?name=John ``` 응답: ```json Hello, John! ``` --- ## **4. `@RequestParam`과 `@PathVariable`의 차이** ### **1) `@RequestParam`: 쿼리 파라미터 받기** ```java @GetMapping("/search") public String search(@RequestParam String keyword) { return "검색어: " + keyword; } ``` - 요청 예시: ``` GET /search?keyword=spring ``` - 응답: `"검색어: spring"` --- ### **2) `@PathVariable`: URL 경로 변수 받기** ```java @GetMapping("/user/{id}") public String getUser(@PathVariable int id) { return "User ID: " + id; } ``` - 요청 예시: ``` GET /user/123 ``` - 응답: `"User ID: 123"` --- ## **5. `@PostMapping`을 이용한 데이터 전송 처리** ### **📌 POST 요청을 이용한 폼 데이터 처리** ```java import org.springframework.web.bind.annotation.*; @RestController public class UserController { @PostMapping("/user") public String createUser(@RequestParam String name, @RequestParam int age) { return "User Created: " + name + ", Age: " + age; } } ``` - 요청 예시 (POST 요청): ``` POST /user Content-Type: application/x-www-form-urlencoded name=John&age=25 ``` - 응답: ``` User Created: John, Age: 25 ``` --- ## **6. `@RequestBody`를 이용한 JSON 데이터 처리** `@RequestBody`를 사용하면 **JSON 데이터를 Java 객체로 변환**할 수 있습니다. ```java import org.springframework.web.bind.annotation.*; @RestController public class UserController { static class User { public String name; public int age; } @PostMapping("/user") public String createUser(@RequestBody User user) { return "User Created: " + user.name + ", Age: " + user.age; } } ``` ### **✅ 실행 예시** 요청 (POST 요청, JSON 데이터 전달): ```json POST /user Content-Type: application/json { "name": "Alice", "age": 30 } ``` 응답: ```json User Created: Alice, Age: 30 ``` --- ## **7. `@ResponseEntity`를 활용한 응답 제어** `ResponseEntity`를 사용하면 **HTTP 상태 코드와 응답을 함께 제어**할 수 있습니다. ```java import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @RestController public class ResponseController { @GetMapping("/status") public ResponseEntity getStatus() { return ResponseEntity.ok("서버 정상 작동 중"); } @GetMapping("/error") public ResponseEntity getError() { return ResponseEntity.status(400).body("잘못된 요청입니다."); } } ``` ### **✅ 실행 예시** - 정상 요청: ``` GET /status ``` 응답: `200 OK`, `"서버 정상 작동 중"` - 오류 요청: ``` GET /error ``` 응답: `400 Bad Request`, `"잘못된 요청입니다."` --- ## **8. `@ExceptionHandler`를 활용한 예외 처리** ```java import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @RestController public class ExceptionController { @GetMapping("/divide") public int divide(@RequestParam int a, @RequestParam int b) { return a / b; // b가 0이면 오류 발생 } @ExceptionHandler(ArithmeticException.class) public ResponseEntity handleArithmeticException() { return ResponseEntity.status(400).body("0으로 나눌 수 없습니다."); } } ``` ### **✅ 실행 예시** - 정상 요청: ``` GET /divide?a=10&b=2 ``` 응답: `5` - 오류 요청 (`b=0`): ``` GET /divide?a=10&b=0 ``` 응답: `400 Bad Request`, `"0으로 나눌 수 없습니다."` --- ## **🔍 정리** Spring Boot MVC에서 컨트롤러를 사용하면 **HTTP 요청을 처리하고, 클라이언트에게 적절한 응답을 반환**할 수 있습니다. - `@Controller`: HTML 뷰 반환 - `@RestController`: JSON 응답 반환 - `@RequestParam`, `@PathVariable`: 요청 데이터 받기 - `@PostMapping` + `@RequestBody`: JSON 데이터 처리 - `ResponseEntity`: 응답 제어 - `@ExceptionHandler`: 예외 처리 **이제 실무에서도 자신 있게 컨트롤러를 활용해 보세요!**