2025-04-08T19:56:24
This commit is contained in:
183
docs/path.md
Normal file
183
docs/path.md
Normal file
@@ -0,0 +1,183 @@
|
||||
스프링 부트에서 컨트롤러의 경로를 지정하는 방법과 전체 요청 경로를 얻는 방법을 설명하겠습니다. 스프링 부트는 주로 `@RequestMapping`과 그 파생 어노테이션을 사용해 경로를 정의하며, 요청 경로를 얻기 위해 `HttpServletRequest` 등의 객체를 활용할 수 있습니다.
|
||||
|
||||
---
|
||||
|
||||
### 1. 컨트롤러에서 경로 지정 방법
|
||||
|
||||
스프링 부트의 컨트롤러에서 경로는 클래스 수준과 메서드 수준에서 정의할 수 있으며, `@RequestMapping` 또는 HTTP 메서드별 전용 어노테이션(`@GetMapping`, `@PostMapping` 등)을 사용합니다.
|
||||
|
||||
#### (1) 클래스 수준 경로 지정
|
||||
컨트롤러 클래스에 `@RequestMapping`을 사용하면 해당 클래스의 모든 메서드에 공통 경로가 적용됩니다.
|
||||
|
||||
- **예시**:
|
||||
```java
|
||||
@RestController
|
||||
@RequestMapping("/api/users")
|
||||
public class UserController {
|
||||
@GetMapping
|
||||
public String getUsers() {
|
||||
return "All users";
|
||||
}
|
||||
|
||||
@GetMapping("/active")
|
||||
public String getActiveUsers() {
|
||||
return "Active users";
|
||||
}
|
||||
}
|
||||
```
|
||||
- `/api/users`: 모든 사용자 조회.
|
||||
- `/api/users/active`: 활성 사용자 조회.
|
||||
|
||||
#### (2) 메서드 수준 경로 지정
|
||||
메서드에 경로를 추가로 지정하면 클래스 경로와 결합됩니다.
|
||||
|
||||
- **예시**:
|
||||
```java
|
||||
@RestController
|
||||
@RequestMapping("/api")
|
||||
public class ProductController {
|
||||
@GetMapping("/products")
|
||||
public String getProducts() {
|
||||
return "Product list";
|
||||
}
|
||||
|
||||
@PostMapping("/products")
|
||||
public String createProduct() {
|
||||
return "Product created";
|
||||
}
|
||||
}
|
||||
```
|
||||
- `/api/products` (GET): 제품 목록 조회.
|
||||
- `/api/products` (POST): 제품 생성.
|
||||
|
||||
#### (3) 경로 변수 사용 (@PathVariable)
|
||||
URL에 동적인 값을 포함하려면 `{변수명}`을 정의하고 `@PathVariable`로 값을 가져옵니다.
|
||||
|
||||
- **예시**:
|
||||
```java
|
||||
@RestController
|
||||
@RequestMapping("/api/users")
|
||||
public class UserController {
|
||||
@GetMapping("/{id}")
|
||||
public String getUserById(@PathVariable Long id) {
|
||||
return "User ID: " + id;
|
||||
}
|
||||
}
|
||||
```
|
||||
- `/api/users/123`: ID가 123인 사용자 조회.
|
||||
|
||||
#### (4) 쿼리 파라미터 사용 (@RequestParam)
|
||||
쿼리 문자열(`?key=value`)을 처리하려면 `@RequestParam`을 사용합니다.
|
||||
|
||||
- **예시**:
|
||||
```java
|
||||
@RestController
|
||||
@RequestMapping("/api/search")
|
||||
public class SearchController {
|
||||
@GetMapping
|
||||
public String search(@RequestParam String query) {
|
||||
return "Search result for: " + query;
|
||||
}
|
||||
}
|
||||
```
|
||||
- `/api/search?query=book`: "book"에 대한 검색 결과.
|
||||
|
||||
#### (5) 복잡한 경로 패턴
|
||||
정규식이나 와일드카드(`*`, `**`)를 사용해 유연한 경로를 정의할 수 있습니다.
|
||||
|
||||
- **예시**:
|
||||
```java
|
||||
@RestController
|
||||
public class FileController {
|
||||
@GetMapping("/files/{filename:.+}")
|
||||
public String getFile(@PathVariable String filename) {
|
||||
return "File: " + filename;
|
||||
}
|
||||
}
|
||||
```
|
||||
- `/files/report.pdf`: 파일 이름에 확장자 포함 가능.
|
||||
|
||||
#### (6) HTTP 메서드별 어노테이션
|
||||
`@RequestMapping` 대신 특정 HTTP 메서드에 맞는 어노테이션을 사용할 수 있습니다:
|
||||
- `@GetMapping`: GET 요청.
|
||||
- `@PostMapping`: POST 요청.
|
||||
- `@PutMapping`: PUT 요청.
|
||||
- `@DeleteMapping`: DELETE 요청.
|
||||
- `@PatchMapping`: PATCH 요청.
|
||||
|
||||
---
|
||||
|
||||
### 2. 전체 요청 경로 얻는 방법
|
||||
|
||||
컨트롤러에서 현재 요청의 전체 경로를 얻으려면 `HttpServletRequest` 객체를 주입받아 사용하거나, 스프링의 유틸리티 메서드를 활용할 수 있습니다.
|
||||
|
||||
#### (1) HttpServletRequest 사용
|
||||
`HttpServletRequest`를 메서드 파라미터로 추가하면 요청 정보를 얻을 수 있습니다.
|
||||
|
||||
- **예시**:
|
||||
```java
|
||||
@RestController
|
||||
@RequestMapping("/api")
|
||||
public class PathController {
|
||||
@GetMapping("/path")
|
||||
public String getFullPath(HttpServletRequest request) {
|
||||
String fullPath = request.getRequestURI(); // 경로만 (/api/path)
|
||||
String query = request.getQueryString(); // 쿼리 문자열 (예: name=john)
|
||||
String fullUrl = request.getRequestURL().toString(); // 전체 URL (http://localhost:8080/api/path)
|
||||
return "Full Path: " + fullPath + ", Query: " + (query != null ? query : "none") + ", Full URL: " + fullUrl;
|
||||
}
|
||||
}
|
||||
```
|
||||
- 요청: `http://localhost:8080/api/path?name=john`
|
||||
- 응답: `"Full Path: /api/path, Query: name=john, Full URL: http://localhost:8080/api/path"`
|
||||
|
||||
- **주요 메서드**:
|
||||
- `getRequestURI()`: 컨텍스트 루트 이후의 경로 반환.
|
||||
- `getQueryString()`: 쿼리 문자열 반환.
|
||||
- `getRequestURL()`: 전체 URL 반환 (쿼리 제외).
|
||||
|
||||
#### (2) RequestContextHolder 사용
|
||||
`HttpServletRequest`를 직접 주입받지 않고, 정적 메서드로 요청 정보를 얻을 수 있습니다.
|
||||
|
||||
- **예시**:
|
||||
```java
|
||||
@RestController
|
||||
@RequestMapping("/api")
|
||||
public class PathController {
|
||||
@GetMapping("/path")
|
||||
public String getFullPath() {
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
HttpServletRequest request = attributes.getRequest();
|
||||
return "Full Path: " + request.getRequestURI();
|
||||
}
|
||||
}
|
||||
```
|
||||
- 장점: 메서드 파라미터 없이도 사용 가능 (예: 서비스 계층에서).
|
||||
|
||||
#### (3) 전체 경로와 함께 컨텍스트 경로 고려
|
||||
애플리케이션이 서블릿 컨테이너에서 실행될 경우, 컨텍스트 경로(예: `/myapp`)가 추가될 수 있습니다. 이를 포함하려면:
|
||||
- `request.getContextPath()`: 컨텍스트 경로 반환 (기본값: 빈 문자열).
|
||||
- 전체 경로: `request.getContextPath() + request.getRequestURI()`.
|
||||
|
||||
---
|
||||
|
||||
### 3. 추가 팁
|
||||
- **경로 충돌 방지**: 동일한 경로에 대해 HTTP 메서드로 구분하거나, 경로를 명확히 분리하세요.
|
||||
- **중첩 경로**: 클래스와 메서드 경로가 결합되므로, 설계 시 중복을 피하도록 주의하세요.
|
||||
- **로깅**: 전체 경로를 로깅하여 디버깅에 활용할 수 있습니다.
|
||||
```java
|
||||
@Slf4j
|
||||
@RestController
|
||||
public class LogController {
|
||||
@GetMapping("/test")
|
||||
public String logPath(HttpServletRequest request) {
|
||||
log.info("Request Path: {}", request.getRequestURI());
|
||||
return "Logged";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 결론
|
||||
스프링 부트에서 경로는 `@RequestMapping`과 그 파생 어노테이션으로 유연하게 지정할 수 있으며, 경로 변수와 쿼리 파라미터를 통해 동적 요청을 처리할 수 있습니다. 전체 요청 경로는 `HttpServletRequest`나 `RequestContextHolder`를 사용해 쉽게 얻을 수 있어, 로깅이나 디버깅에 유용합니다. 이를 통해 RESTful API나 MVC 구조를 깔끔하게 설계할 수 있습니다. 추가 질문이 있다면 말씀해주세요!
|
||||
Reference in New Issue
Block a user