지난 포스팅에 이어서, Controller에 대해 알아보도록 하자.
Spring MVC의 Controller
- Spring MVC에서 Controller(컨트롤러)는 클라이언트의 요청을 받아 비즈니스 로직(Service)과 View(예를 들면, Thymeleaf)를 연결하는 역할을 한다.
- Controller는 사용자 요청을 처리하고, 데이터를 Model에 담아 View로 전달하는 역할을 한다.
Controller의 역할
- 클라이언트의 HTTP 요청을 처리한다.
- Service를 호출하여 비즈니스 로직을 수행한다.
- Model을 사용하여 View로 데이터 전달
- REST API를 제공하는 경우 JSON 응답 반환 가능하다.
Controller는 클라이언트(View 또는 API 요청)와 Service 간의 다리 역할을 수행한다고 생각하면 된다.
클라이언트 → Controller → Service → Repository → Entity → DB → Entity → Repository → Service → Controller → Model → View(Thymeleaf) → 클라이언트 응답
📍 참고로, 여기에 있는 Model은 MVC 패턴의 Model과 같은 것이 아니다.
이제, 기본적인 예제를 살펴보도록 하자.
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", "Spring MVC 프로젝트에 오신 것을 환영합니다!");
return "home"; // home.html로 이동
}
}
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.List;
@Controller
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/users")
public String getUsers(Model model) {
List<UserDTO> users = userService.getAllUsers();
model.addAttribute("users", users);
return "user-list"; // user-list.html로 이동
}
}
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class SearchController {
@GetMapping("/search")
public String search(@RequestParam String keyword, Model model) {
model.addAttribute("keyword", keyword);
return "search-results";
}
}
<p>검색어: <span th:text="${keyword}"></span></p>
어노테이션이 굉장히 많은데, 어노테이션을 이해하면 Controller를 이해하기 더 쉬울 것이다.
다음으로 Controller에서 주로 사용하는 어노테이션에 대해 알아보자.
1. @Controller vs @RestController
Controller를 정의할 때 가장 많이 사용하는 어노테이션이다.
@Controller
public class HomeController {
@GetMapping("/")
public String home(Model model) {
model.addAttribute("message", "Spring MVC 프로젝트!");
return "home"; // home.html 템플릿 반환
}
}
@RestController
@RequestMapping("/api")
public class ApiController {
@GetMapping("/message")
public String getMessage() {
return "Hello, this is a REST API response!";
}
}
@Controller
@ResponseBody
public class ExampleController {
@GetMapping("/json")
public String getJson() {
return "{\"message\": \"Hello, JSON!\"}";
}
}
2. @RequestMapping vs @GetMapping vs @PostMapping
Spring에서 HTTP 요청을 처리하기 위해 사용되는 매핑 어노테이션이다.
: 공통 URL 패턴, 즉 모든 html 메서드(GET, POST, PUT 등)을 매핑하는 어노테이션이다.
@Controller
@RequestMapping("/users")
public class UserController {
@RequestMapping("/list")
public String getUserList() {
return "user-list"; // user-list.html 반환
}
}
: HTTP GET 요청을 처리한다.
: HTTP POST 요청을 처리한다.
@Controller
@RequestMapping("/users")
public class UserController {
@GetMapping("/list")
public String getUsers() {
return "user-list"; // GET 요청
}
@PostMapping("/add")
public String addUser() {
return "redirect:/users/list"; // POST 요청
}
}
3. @RequestParam vs @PathVariable
클라이언트가 보낸 데이터를 받을 때 사용하는 어노테이션이다.
@Controller
@RequestMapping("/search")
public class SearchController {
@GetMapping
public String search(@RequestParam String keyword, Model model) {
model.addAttribute("keyword", keyword);
return "search-results"; // search-results.html 반환
}
}
@RestController
@RequestMapping("/api/users")
public class UserRestController {
@GetMapping("/{id}")
public String getUserById(@PathVariable Long id) {
return "User ID: " + id;
}
}
요청은 http: //localhost:8080/api/users/10의 형태이며 @PathVariable을 사용하여 id=10 값을 가져온다.
4. @ModelAttribute vs @RequestBody
마지막으로, 사용자로부터 폼 데이터를 받을 때 사용하는 어노테이션이다.
: 폼 데이터를 객체로 변환한다. (Form (HTML)형식)
@Controller
@RequestMapping("/users")
public class UserController {
@PostMapping("/form")
public String submitUserForm(@ModelAttribute UserDTO userDTO) {
System.out.println("Name: " + userDTO.getName());
System.out.println("Email: " + userDTO.getEmail());
return "redirect:/users";
}
}
<form action="/users/form" method="post">
<input type="text" name="name" placeholder="이름" />
<input type="email" name="email" placeholder="이메일" />
<button type="submit">제출</button>
</form>
제출
: JSON 데이터를 객체로 변환한다.
@RestController
@RequestMapping("/api/users")
public class UserRestController {
@PostMapping
public String createUser(@RequestBody UserDTO userDTO) {
return "User created: " + userDTO.getName();
}
}
{
"name": "홍길동",
"email": "hong@example.com"
}