
현대 스프링 MVC는 SSR에서 CSR로 전환됨에 따라, 백엔드는 더이상 View 렌더링이 아닌 Data(JSON)로 응답한다.
@Controller전통적인 MVC 컨트롤러
@RestController@Controller + @ResponseBody
@ResponseBody@RestController가 붙은 컨트롤러는 모든 메서드에 @ResponseBody 어노테이션이 붙어있다고 간주아래 코드 1과 코드 2는 완전히 동일하다!
@Controller + @ResponseBodyimport org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController {
@RequestMapping(value = "/users", method = RequestMethod.GET)
@ResponseBody
public User getUser() {
// ...
}
}
@RestControllerimport org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController // @Controller와 @ResponseBody가 합쳐졌다!
public class UserRestController {
@RequestMapping(value = "/users", method = RequestMethod.GET)
public User getUser() {
// ...
}
}
요청과 컨트롤러의 메서드를 매핑하는데 사용
@RequestMapping
@RestController
@RequestMapping("/hello")
public class HelloController {
// ...
}
@RequestMapping(value = "/hello", method = RequestMethod.GET)으로 후술할 @GetMapping("/hello")와 같은 효과를 얻을 수 있지만, 잘 쓰지 않는다.@GetMapping, @PostMapping, @PutMapping, @PatchMapping, @DeleteMapping
@RestController
public class HelloController {
@GetMapping("/hello")
public void getHello() {
// ...
}
}
@RequestParam? 뒤에 오는 쿼리 문자열 처리 (웹 기초 - URL 구성 요소 참조)예시: GET /users?name=john&age=30 요청을 처리할 때
@RestController
public class UserController {
@GetMapping("/users")
public String getUser(
@RequestParam String name, // name 값은 john
@RequestParam int age // age 값은 30
) {
// ...
}
}
@RequestParam(required = false): 해당 파라미터가 선택 파라미터가 된다.@RequestParam(defaultValue = "value"): 선택 파라미터가 되며, 쿼리에 파라미터가 없을 경우 해당 기본값으로 설정된다.@RestController
public class UserController {
// /users?page=1 요청이 들어온 상황이라면
@GetMapping("/users")
public List<String> getUsers(
@RequestParam(defaultValue = "0") int page, // 1
@RequestParam(defaultValue = "10") int size, // 10
@RequestParam(required = false) String sort // null
) {
// ...
}
}
@ModelAttribute: 폼 데이터 or 여러 파라미터@ModelAttribute@RequestParam을 붙이기엔 번거롭다.// @RequestParam이 너무 많은 경우
@GetMapping("/api/search")
public List<String> searchUsers(
@RequestParam(required = false) String name,
@RequestParam(required = false) String email,
@RequestParam(required = false) Integer minAge,
@RequestParam(required = false) Integer maxAge,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "10") int size
) {
// 파라미터가 많아서 복잡함!
}
// @ModelAttribute 사용 (추천)
@GetMapping("/api/search")
public List<String> searchUsers(@ModelAttribute UserSearchDto dto) {
// 하나의 @ModelAttribute로 데이터를 받을 수 있다.
}
// 바인딩용 DTO 클래스
public class UserSearchDto {
private String name;
private String email;
private Integer minAge;
private Integer maxAge;
private Integer page = 0; // 기본값 설정 가능
private Integer size = 10; // 기본값 설정 가능
// ...
}
Content-Type: application/x-www-form-urlencoded인 경우@PathVariable: 경로 변수@PathVariable@RequsetParam과 달리, 쿼리가 아닌 Path에서 값을 얻는다.@RestController
public class UserController {
// GET /users/123
@GetMapping("/users/{userId}")
public String getUser(@PathVariable Long userId) { // userId는 123
// ...
}
}
/posts/123과 /posts는 다른 API이다./users?nickname=gwangmin과 /users는 같은 API이다.@RequestBody: 요청 본문@RequestBody@RestController
public class UserController {
// POST /users
// Body: {"name": "John", "email": "john@example.com", "age": 30}
@PostMapping("/users")
public String createUser(@RequestBody CreateUserRequest request) {
// ...
}
}
@Getter
public class CreateUserRequest {
// 위의 요청의 경우 아래와 같이 값이 매핑됩니다.
private String name; // John
private String email; // john@example.com
private int age; // 30
}