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 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) |
5. 고급 사용 사례: 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();
}
6. 주요 설계 원칙
- 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/*";
}
매칭 규칙과 특징
(1) 정확한 세그먼트만 매칭
- /files/* → 정확히 한 세그먼트만 대체 가능.
- /files/*/edit → 중간 세그먼트 하나만 대체.
(2) 슬래시(/) 경계
- *는 슬래시(/)를 포함하지 않는 경로 조각만 대체합니다.
- /users/*는 /users/홍길동과 매칭되지만 /users/홍길동/프로필과는 매칭되지 않습니다.
*와 **의 차이점
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;
}
}
'Backend > Spring' 카테고리의 다른 글
| [Spring Web MVC] Session (0) | 2024.11.25 |
|---|---|
| [Spring Web MVC] 🍪Cookie (0) | 2024.11.25 |
| [기록]JSP로 페이징 구현 (0) | 2024.11.22 |
| [board_기록] 답글이 있는 게시판 만들기 (0) | 2024.11.22 |
| @Controller와 @RestController의 차이점 (1) | 2024.11.21 |