Spring Boot의 @RequestMapping은 Spring MVC에서 HTTP 요청을 특정 컨트롤러 메서드에 매핑하기 위해 사용됩니다. 웹 애플리케이션 개발에서 URL 경로와 해당 경로를 처리할 메서드를 연결하는 중요한 어노테이션입니다.
1. @RequestMapping의 기본 개념
- 역할: HTTP 요청(예: GET, POST, PUT, DELETE 등)을 특정 컨트롤러 클래스나 메서드에 매핑합니다.
- 적용 위치:
- 클래스 레벨: 기본 URL 경로 설정.
- 메서드 레벨: 세부 경로 및 HTTP 메서드 설정.
2. 주요 속성 (Attributes)
속성 | 설명 | 예시 |
value 또는 path | 요청 URL 경로를 지정. 단일 경로나 배열 형태로 가능. | @RequestMapping("/users") |
method | HTTP 메서드 지정 (GET, POST, PUT, DELETE 등). 여러 개 지정 가능. | @RequestMapping(value = "/users", method = RequestMethod.GET) |
params | 요청에 특정 쿼리 파라미터가 포함되어야 매핑되도록 설정. | @RequestMapping(value = "/users", params = "active=true") |
headers | 요청 헤더 조건에 따라 매핑. | @RequestMapping(value = "/users", headers = "X-Header=abc") |
consumes | 요청 본문(Content-Type) 조건을 지정 (JSON, XML 등). | @RequestMapping(value = "/users", consumes = "application/json") |
produces | 응답 본문(Content-Type)을 지정. 클라이언트가 기대하는 데이터 형식을 명시. | @RequestMapping(value = "/users", produces = "application/json") |
3. @RequestMapping과 HTTP 메서드
@RequestMapping은 HTTP 메서드를 명시적으로 지정하지 않으면 모든 메서드(GET, POST, etc.)를 처리합니다.
하지만 더 명확한 코드 작성과 유지보수를 위해 각 HTTP 메서드에 특화된 매핑 어노테이션을 사용하는 것이 일반적입니다:
어노테이션 | 설명 |
@GetMapping | HTTP GET 요청을 처리. |
@PostMapping | HTTP POST 요청을 처리. |
@PutMapping | HTTP PUT 요청을 처리. |
@DeleteMapping | HTTP DELETE 요청을 처리. |
@PatchMapping | HTTP PATCH 요청을 처리. |
4. @RequestMapping의 활용 예제
(1) 클래스 레벨과 메서드 레벨의 매핑
클래스 레벨에서 공통 경로를 지정하고, 메서드 레벨에서 세부 경로를 설정할 수 있습니다.
@RestController
@RequestMapping("/api/users")
public class UserController {
// GET /api/users
@GetMapping
public List<String> getUsers() {
return List.of("홍길동", "박문수", "이몽룡");
}
// GET /api/users/{id}
@GetMapping("/{id}")
public String getUserById(@PathVariable Long id) {
return "User ID: " + id;
}
// POST /api/users
@PostMapping
public String createUser(@RequestBody Map<String, String> user) {
return "User created: " + user.get("name");
}
}
(2) HTTP 메서드 지정
특정 HTTP 메서드만 처리하도록 설정할 수 있습니다.
@RequestMapping(value = "/products", method = RequestMethod.POST)
public String addProduct() {
return "Product added!";
}
(3) 쿼리 파라미터 기반 매핑
요청에 특정 쿼리 파라미터가 포함된 경우에만 매핑됩니다.
@RequestMapping(value = "/search", params = "keyword")
public String search(@RequestParam String keyword) {
return "Search result for: " + keyword;
}
(4) 헤더 기반 매핑
특정 요청 헤더가 포함된 요청만 처리합니다.
@RequestMapping(value = "/header-test", headers = "X-Special-Header=Valid")
public String headerTest() {
return "Header matched!";
}
(5) 콘텐츠 타입 제약
- Consumes: 요청 본문의 Content-Type이 특정 조건을 만족해야 매핑됩니다.
- Produces: 응답의 Content-Type을 지정합니다.
@RequestMapping(value = "/json-endpoint", consumes = "application/json", produces = "application/json")
public Map<String, String> jsonEndpoint(@RequestBody Map<String, String> input) {
input.put("status", "processed");
return input;
}
5. @RequestMapping vs 단축 어노테이션
단축 어노테이션 | @RequestMapping 사용 시 동일 코드 |
@GetMapping("/users") | @RequestMapping(value = "/users", method = RequestMethod.GET) |
@PostMapping("/users") | @RequestMapping(value = "/users", method = RequestMethod.POST) |
@PutMapping("/users") | @RequestMapping(value = "/users", method = RequestMethod.PUT) |
단축 어노테이션을 사용하면 코드가 간결해지고, HTTP 메서드를 더 명확하게 표현할 수 있습니다.
6. 고급 사용 사례: URI 변수와 매개변수
(1) PathVariable
URI의 변수 값을 추출하여 메서드 매개변수로 전달합니다.
@GetMapping("/users/{id}")
public String getUser(@PathVariable("id") Long id) {
return "User ID: " + id;
}
(2) RequestParam
쿼리 파라미터 값을 추출합니다.
@GetMapping("/search")
public String search(@RequestParam("q") String query) {
return "Searching for: " + query;
}
(3) RequestBody
요청 본문(JSON 또는 XML)을 매핑하여 객체로 변환합니다.
@PostMapping("/users")
public String createUser(@RequestBody User user) {
return "User created: " + user.getName();
}
7. 주요 설계 원칙
- RESTful 설계:
- @RequestMapping은 RESTful API 설계에 적합하며, 리소스 경로(URL)와 HTTP 메서드를 조합해 일관된 인터페이스를 제공합니다.
- 단일 책임 원칙:
- 하나의 컨트롤러 메서드는 하나의 작업만 처리하도록 설계합니다.
- 명확성:
- HTTP 메서드와 경로를 명확히 정의하여 요청과 매핑 로직 간의 모호성을 줄입니다.
애스터리스크(*)의 의미
- 단일 경로 세그먼트에 대해 매칭합니다.
- URL의 특정 부분을 대체할 수 있는 와일드카드로 사용됩니다.
- 한 세그먼트는 슬래시(/)로 구분된 URL의 한 조각을 의미합니다.
- 예: /users/* → /users/홍길동은 매칭되지만 /users/admin/settings은 매칭되지 않음.
(1) 단일 경로 세그먼트 매칭
- ``는 슬래시(/) 사이에 있는 하나의 경로 조각만 대체할 수 있습니다.
@RequestMapping("/files/*")
public String handleSingleWildcard() {
return "Matches any single segment under /files/";
}
예시:
- 매칭: /files/image, /files/document
- 매칭되지 않음: /files/images/picture, /files/
(2) PathVariable과 함께 사용
- ``와 @PathVariable을 조합해 와일드카드로 추출된 경로 세그먼트를 변수로 받을 수 있습니다.
@RequestMapping("/users/*")
public String handleUserWildcard(@PathVariable String id) {
return "User ID: " + id;
}
주의: Spring MVC에서는 *를 사용할 경우, PathVariable의 이름을 명시적으로 지정할 수 없습니다. URL의 매칭 부분을 동적으로 처리하려면 더 구체적인 패턴 매칭이 필요합니다.
(3) 다중 경로 매칭
- ``를 배열로 사용하여 다양한 경로를 한 번에 매핑할 수 있습니다.
@RequestMapping({"/users/*", "/admins/*"})
public String handleMultipleWildcards() {
return "Matches both /users/* and /admins/*";
}
3. 매칭 규칙과 특징
(1) 정확한 세그먼트만 매칭
- /files/* → 정확히 한 세그먼트만 대체 가능.
- /files/*/edit → 중간 세그먼트 하나만 대체.
(2) 슬래시(/) 경계
- ``는 슬래시(/)를 포함하지 않는 경로 조각만 대체합니다.
- /users/*는 /users/홍길동과 매칭되지만 /users/홍길동/프로필과는 매칭되지 않습니다.
4. ``와 *의 차이점
Spring MVC에서는 *와 **가 다른 방식으로 작동합니다.
기호 | 의미 | 예시 |
* | 단일 경로 세그먼트를 대체. | /files/* → /files/image, /files/doc |
** | 다중 경로 세그먼트를 대체. 중첩된 경로 전체를 포함. | /files/** → /files/image/picture/doc |
@RequestMapping("/files/**")
public String handleDoubleWildcard() {
return "Matches any nested path under /files/";
}
- * 활용 예시:
- /files/** → /files/images/picture, /files/docs/notes (모두 매칭).
5. 실제 사용 시 주의점
- PathVariable과의 조합
- ``는 단일 세그먼트를 대체하지만, @PathVariable로 사용하려면 명시적인 경로 지정이 필요합니다. 불명확한 매핑은 런타임 오류를 초래할 수 있습니다.
- 우선순위 문제예: /files/image와 /files/*가 동시에 정의된 경우 /files/image가 먼저 매칭됩니다.
- 여러 매핑이 동일한 패턴을 가지거나 유사할 경우, Spring은 보다 구체적인 경로를 우선 처리합니다.
- 유효하지 않은 매칭
- ``는 반드시 단일 경로 세그먼트를 의미하므로, 빈 세그먼트(//)나 중첩된 세그먼트에는 매칭되지 않습니다.
6. 예제 코드: 다양한 애스터리스크 사용
@RestController
@RequestMapping("/api")
public class FileController {
// 단일 세그먼트 매칭
@RequestMapping("/files/*")
public String handleSingleSegment() {
return "Single segment matched!";
}
// 다중 세그먼트 매칭
@RequestMapping("/files/**")
public String handleNestedSegments() {
return "Multiple segments matched!";
}
// PathVariable과 결합
@RequestMapping("/users/*")
public String handleUserWildcard(@PathVariable String id) {
return "User ID matched with wildcard: " + id;
}
}
'Spring' 카테고리의 다른 글
Spring Web MVC - 쿠키(Cookie) (1) | 2024.12.20 |
---|---|
Spring Web MVC - HTTP 요청 파라미터 처리 (1) | 2024.12.20 |
SpringBoot 웹 애플리케이션의 MVC 패턴 (0) | 2024.12.20 |
답글이 있는 게시판 만들기 (1) | 2024.12.20 |
JSP로 페이징 구현하기 (0) | 2024.12.20 |