Loading...
Spring Framework Reference Documentation 7.0.2의 Mapping Requests의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
See equivalent in the Reactive stack
이 섹션에서는 어노테이션이 적용된 컨트롤러에 대한 요청 매핑에 대해 설명합니다.
@RequestMappingSee equivalent in the Reactive stack
@RequestMapping 어노테이션을 사용하여 요청을 컨트롤러 메서드에 매핑할 수 있습니다. 이 어노테이션에는
URL, HTTP 메서드, 요청 파라미터, 헤더, 미디어 타입으로 매칭하기 위한 다양한 속성이 있습니다.
클래스 레벨에서 사용하여 공유되는 매핑을 표현하거나 메서드 레벨에서 사용하여 특정 엔드포인트 매핑으로 범위를 좁힐 수 있습니다.
@RequestMapping의 HTTP 메서드별 쇼트컷 변형도 있습니다:
@GetMapping@PostMapping@PutMapping@DeleteMapping@PatchMapping이 쇼트컷들은
Custom Annotations
으로, 대부분의 컨트롤러 메서드는 기본적으로 모든 HTTP 메서드에 매칭되는 @RequestMapping을 사용하는 것보다
특정 HTTP 메서드에 매핑되어야 한다는 이유로 제공됩니다.
클래스 레벨에서는 여전히 공유되는 매핑을
표현하기 위해 @RequestMapping이 필요합니다.
@RequestMapping은 동일한 요소(class, interface, 또는 method)에 선언된 다른@RequestMapping어노테이션과 함께 사용할 수 없습니다. 동일한 요소에서 여러 개의@RequestMapping어노테이션이 감지되면 경고가 로그에 기록되며 첫 번째 매핑만 사용됩니다. 이는@GetMapping,@PostMapping등과 같은 composed@RequestMapping어노테이션에도 적용됩니다.
다음 예제는 타입 및 메서드 레벨 매핑을 포함합니다:
1@RestController 2@RequestMapping("/persons") 3class PersonController { 4 5 @GetMapping("/{id}") 6 public Person getPerson(@PathVariable Long id) { 7 // ... 8 } 9 10 @PostMapping 11 @ResponseStatus(HttpStatus.CREATED) 12 public void add(@RequestBody Person person) { 13 // ... 14 } 15}
1@RestController 2@RequestMapping("/persons") 3class PersonController { 4 5 @GetMapping("/{id}") 6 fun getPerson(@PathVariable id: Long): Person { 7 // ... 8 } 9 10 @PostMapping 11 @ResponseStatus(HttpStatus.CREATED) 12 fun add(@RequestBody person: Person) { 13 // ... 14 } 15}
See equivalent in the Reactive stack
@RequestMapping 메서드는 URL 패턴을 사용하여 매핑할 수 있습니다.
Spring MVC는 URL 경로를 미리 파싱한 PathContainer에 대해 미리 파싱된 패턴인 PathPattern을 사용합니다.
웹 용도로 설계된 이 솔루션은 인코딩과 경로 파라미터를 효과적으로 처리하고 효율적으로 매칭합니다. 경로 매칭 옵션의 커스터마이징에 대해서는 MVC config를 참조하십시오.
AntPathMatcher변형은 이제 deprecated되었습니다. 이는 효율성이 떨어지고 String 경로 입력이 URL의 인코딩 및 기타 이슈를 효과적으로 처리하는 데 어려움이 있기 때문입니다.
glob 패턴과 와일드카드를 사용하여 요청을 매핑할 수 있습니다:
| Pattern | Description | Example |
|---|---|---|
spring | Literal pattern | "/spring"은 "/spring"과 매칭됩니다 |
? | 한 글자와 매칭 | "/pages/t?st.html"은 "/pages/test.html" 및 "/pages/t3st.html"과 매칭됩니다 |
* | 경로 세그먼트 내에서 0개 이상의 문자와 매칭 | "/resources/*.png"는 "/resources/file.png"와 매칭됩니다.<br>"/projects/*/versions"는 "/projects/spring/versions"와 매칭되지만 "/projects/spring/boot/versions"와는<br>매칭되지 않습니다.<br>"/projects/*"는 "/projects/spring"과 매칭되지만 경로 세그먼트가 존재하지 않기 때문에 "/projects"와는<br>매칭되지 않습니다. |
** | 0개 이상의 경로 세그먼트와 매칭 | "/resources/**"는 "/resources", "/resources/file.png" 및 "/resources/images/file.png"와 매칭됩니다.<br>"/**/info"는 "/info", "/spring/info" 및 "/spring/framework/info"와 매칭됩니다.<br>"/resources/**/file.png"는 경로 중간에 **가 허용되지 않으므로 유효하지 않습니다.<br>"/**/spring/**"는 패턴당 하나의 **/{*path} 인스턴스만 허용되므로 허용되지 않습니다. |
{name} | *와 유사하지만 경로 세그먼트를 "name"이라는 이름의 변수로 캡처합니다 | "/projects/{project}/versions"는 "/projects/spring/versions"와 매칭되고 project=spring을 캡처합니다.<br>"/projects/{project}/versions"는 하나의 경로 세그먼트만 캡처하므로 "/projects/spring/framework/versions"와는<br>매칭되지 않습니다. |
{name:[a-z]+} | "name"이라는 이름의 경로 변수로 정규식 "[a-z]+"와 매칭 | "/projects/{project:[a-z]+}/versions"는 "/projects/spring/versions"와 매칭되지만<br>"/projects/spring1/versions"와는 매칭되지 않습니다 |
{*path} | **와 유사하지만 "path"라는 이름의 변수로 경로 세그먼트를 캡처합니다 | "/resources/{*file}"는 "/resources/images/file.png"와 매칭되고 file=/images/file.png를 캡처합니다.<br>"{*path}/resources"는 "/spring/framework/resources"와 매칭되고 path=/spring/framework를 캡처합니다.<br>"/resources/{*path}/file.png"는 경로 중간에 {*path}가 허용되지 않으므로 유효하지 않습니다.<br>"/{*path}/spring/**"는 패턴당 하나의 **/{*path} 인스턴스만 허용되므로 허용되지 않습니다. |
캡처된 URI 변수는 @PathVariable로 접근할 수 있습니다. 예:
1@GetMapping("/owners/{ownerId}/pets/{petId}") 2public Pet findPet(@PathVariable Long ownerId, @PathVariable Long petId) { 3 // ... 4}
1@GetMapping("/owners/{ownerId}/pets/{petId}") 2fun findPet(@PathVariable ownerId: Long, @PathVariable petId: Long): Pet { 3 // ... 4}
다음 예에서 보듯이 클래스 및 메서드 레벨에서 URI 변수를 선언할 수 있습니다:
1@Controller 2@RequestMapping("/owners/{ownerId}") 3public class OwnerController { 4 5 @GetMapping("/pets/{petId}") 6 public Pet findPet(@PathVariable Long ownerId, @PathVariable Long petId) { 7 // ... 8 } 9}
1@Controller 2@RequestMapping("/owners/{ownerId}") 3class OwnerController { 4 5 @GetMapping("/pets/{petId}") 6 fun findPet(@PathVariable ownerId: Long, @PathVariable petId: Long): Pet { 7 // ... 8 } 9}
URI 변수는 적절한 타입으로 자동 변환되며, 그렇지 않으면 TypeMismatchException이
발생합니다. 기본적으로 단순 타입(int, long, Date 등)이 지원되며
다른 데이터 타입에 대한 지원을 등록할 수 있습니다.
Type Conversion 및
DataBinder를 참조하십시오.
URI 변수 이름을 명시적으로 지정할 수 있습니다(예: @PathVariable("customId")). 그러나
이름이 동일하고 코드를 -parameters 컴파일러 플래그와 함께 컴파일한 경우에는
이 세부 사항을 생략할 수 있습니다.
{varName:regex} 문법은 {varName:regex} 문법을 가진 정규 표현식이 있는 URI 변수를
선언합니다. 예를 들어 URL "/spring-web-3.0.5.jar"가 주어졌을 때, 다음 메서드는
name, version 및 파일 확장자를 추출합니다:
1@GetMapping("/{name:[a-z-]+}-{version:\d\.\d\.\d}{ext:\.[a-z]+}") 2public void handle(@PathVariable String name, @PathVariable String version, @PathVariable String ext) { 3 // ... 4}
1@GetMapping("/{name:[a-z-]+}-{version:\d\.\d\.\d}{ext:\.[a-z]+}") 2fun handle(@PathVariable name: String, @PathVariable version: String, @PathVariable ext: String) { 3 // ... 4}
URI 경로 패턴은 다음을 가질 수도 있습니다:
PropertySourcesPlaceholderConfigurer를 통해 local, system, environment 및
기타 프로퍼티 소스에 대해 resolve되는 embedded ${…} 플레이스홀더.
이는 예를 들어 외부 설정을 기반으로 base URL을 파라미터화하는 데 유용합니다.#{…}.See equivalent in the Reactive stack
여러 패턴이 URL과 매칭될 때는 가장 적합한 매치를 선택해야 합니다. 이는
파싱된 PathPattern 사용이 활성화되었는지 여부에 따라 다음 중 하나로 수행됩니다:
두 comparator 모두 더 구체적인 패턴이 위에 오도록 패턴을 정렬하는 데 도움을 줍니다. 패턴은 URI 변수(1로 계산), 단일 와일드카드(1로 계산), 이중 와일드카드(2로 계산)의 개수가 더 적으면 더 구체적입니다.
점수가 동일한 경우 더 긴 패턴이 선택됩니다. 점수와 길이가 동일한 경우 와일드카드보다 URI 변수가 더 많은 패턴이 선택됩니다.
기본 매핑 패턴(/**)은 점수 계산에서 제외되며 항상
마지막에 정렬됩니다. 또한 prefix 패턴(예: /public/**)은
이중 와일드카드가 없는 다른 패턴보다 덜 구체적인 것으로 간주됩니다.
전체 세부 사항은 위의 패턴 Comparator 링크를 참조하십시오.
reflected file download(RFD) 공격은 요청 입력(예: 쿼리 파라미터 및 URI 변수)이 응답에 반영된다는 점에서 XSS와 유사합니다. 그러나 HTML에 JavaScript를 삽입하는 대신 RFD 공격은 브라우저가 다운로드를 수행하도록 전환하고 나중에 더블 클릭 시 응답을 실행 가능한 스크립트로 처리하는 것에 의존합니다.
Spring MVC에서 @ResponseBody 및 ResponseEntity 메서드는
다양한 콘텐츠 타입을 렌더링할 수 있으므로 위험에 노출됩니다. 클라이언트는 URL 경로 확장자를 통해
이를 요청할 수 있습니다. suffix 패턴 매칭을 비활성화하고 콘텐츠 협상을 위해
경로 확장자를 사용하는 것은 위험을 낮추지만 RFD 공격을 방지하기에는 충분하지 않습니다.
RFD 공격을 방지하기 위해 응답 본문을 렌더링하기 전에 Spring MVC는
Content-Disposition:inline;filename=f.txt 헤더를 추가하여 고정되고 안전한
다운로드 파일을 제안합니다. 이는 URL 경로에 안전한 것으로 허용되지 않았거나
콘텐츠 협상을 위해 명시적으로 등록되지 않은 파일 확장자가 포함된 경우에만 수행됩니다.
그러나 URL을 브라우저에 직접 입력하는 경우 잠재적으로 부작용이 있을 수 있습니다.
많은 일반적인 경로 확장자는 기본적으로 안전한 것으로 허용됩니다.
커스텀 HttpMessageConverter 구현이 있는 애플리케이션은 해당 확장자에 대해
콘텐츠 협상을 위해 파일 확장자를 명시적으로 등록하여 해당 확장자에
Content-Disposition 헤더가 추가되지 않도록 할 수 있습니다.
Content Types를 참조하십시오.
RFD와 관련된 추가 권장 사항은 CVEs-2015-5211을 참조하십시오.
See equivalent in the Reactive stack
다음 예에서 보듯이 요청의 Content-Type을 기준으로
요청 매핑 범위를 좁힐 수 있습니다:
1@PostMapping(path = "/pets", consumes = "application/json") (1) 2public void addPet(@RequestBody Pet pet) { 3 // ... 4}
1 콘텐츠 타입으로 매핑 범위를 좁히기 위해
consumes속성을 사용합니다.
1@PostMapping("/pets", consumes = ["application/json"]) (1) 2fun addPet(@RequestBody pet: Pet) { 3 // ... 4}
1 콘텐츠 타입으로 매핑 범위를 좁히기 위해
consumes속성을 사용합니다.
consumes 속성은 부정 표현도 지원합니다. 예를 들어 !text/plain은
text/plain 이외의 모든 콘텐츠 타입을 의미합니다.
클래스 레벨에서 공유되는 consumes 속성을 선언할 수 있습니다. 그러나
대부분의 다른 요청-매핑 속성과 달리 클래스 레벨에서 사용되는 경우
메서드 레벨의 consumes 속성은 클래스 레벨 선언을 확장하는 것이 아니라
오버라이드합니다.
MediaType은APPLICATION_JSON_VALUE,APPLICATION_XML_VALUE와 같은 일반적으로 사용되는 미디어 타입에 대한 상수를 제공합니다.
See equivalent in the Reactive stack
다음 예에서 보듯이 Accept 요청 헤더 및 컨트롤러 메서드가
생성하는 콘텐츠 타입 목록을 기준으로 요청 매핑 범위를 좁힐 수 있습니다:
1@GetMapping(path = "/pets/{petId}", produces = "application/json") (1) 2@ResponseBody 3public Pet getPet(@PathVariable String petId) { 4 // ... 5}
1 콘텐츠 타입으로 매핑 범위를 좁히기 위해
produces속성을 사용합니다.
1@GetMapping("/pets/{petId}", produces = ["application/json"]) (1) 2@ResponseBody 3fun getPet(@PathVariable petId: String): Pet { 4 // ... 5}
1 콘텐츠 타입으로 매핑 범위를 좁히기 위해
produces속성을 사용합니다.
미디어 타입은 문자 집합을 지정할 수 있습니다. 부정 표현도 지원됩니다. 예를 들어
!text/plain은 "text/plain" 이외의 모든 콘텐츠 타입을 의미합니다.
클래스 레벨에서 공유되는 produces 속성을 선언할 수 있습니다. 그러나
대부분의 다른 요청-매핑 속성과 달리 클래스 레벨에서 사용되는 경우
메서드 레벨의 produces 속성은 클래스 레벨 선언을 확장하는 것이 아니라
오버라이드합니다.
MediaType은APPLICATION_JSON_VALUE,APPLICATION_XML_VALUE와 같은 일반적으로 사용되는 미디어 타입에 대한 상수를 제공합니다.
See equivalent in the Reactive stack
요청 파라미터 조건을 기반으로 요청 매핑 범위를 좁힐 수 있습니다.
요청 파라미터의 존재(myParam), 부재(!myParam) 또는
특정 값(myParam=myValue)을 테스트할 수 있습니다.
다음 예는 특정 값을 테스트하는 방법을 보여줍니다:
1@GetMapping(path = "/pets/{petId}", params = "myParam=myValue") (1) 2public void findPet(@PathVariable String petId) { 3 // ... 4}
1
myParam이myValue와 같은지 테스트합니다.
1@GetMapping("/pets/{petId}", params = ["myParam=myValue"]) (1) 2fun findPet(@PathVariable petId: String) { 3 // ... 4}
1
myParam이myValue와 같은지 테스트합니다.
다음 예에서 보듯이 요청 헤더 조건에서도 동일한 방법을 사용할 수 있습니다:
1@GetMapping(path = "/pets/{petId}", headers = "myHeader=myValue") (1) 2public void findPet(@PathVariable String petId) { 3 // ... 4}
1
myHeader가myValue와 같은지 테스트합니다.
1@GetMapping("/pets/{petId}", headers = ["myHeader=myValue"]) (1) 2fun findPet(@PathVariable petId: String) { 3 // ... 4}
1
myHeader가myValue와 같은지 테스트합니다.
헤더 조건으로
Content-Type및Accept를 매칭할 수 있지만, consumes 및 produces를 대신 사용하는 것이 더 좋습니다.
See equivalent in the Reactive stack
API 버전을 지정하는 표준 방법은 없으므로 MVC Config에서 API 버전 관리를 활성화할 때 버전을 resolve하는 방법을 지정해야 합니다. MVC Config는 ApiVersionStrategy를 생성하며, 이는 요청을 매핑하는 데 사용됩니다.
API 버전 관리가 활성화되면 버전을 사용하여 요청 매핑을 시작할 수 있습니다.
@RequestMapping``version 속성은 다음을 지원합니다:
여러 컨트롤러 메서드가 요청 버전보다 작거나 같은 버전을 가진 경우, 그 중 가장 높고 요청 버전에 가장 가까운 것이 고려되며, 실질적으로 나머지를 대체합니다.
이를 설명하기 위해 다음 매핑을 살펴보겠습니다:
1@RestController 2@RequestMapping("/account/{id}") 3public class AccountController { 4 5 @GetMapping (1) 6 public Account getAccount() { 7 } 8 9 @GetMapping(version = "1.1") (2) 10 public Account getAccount1_1() { 11 } 12 13 @GetMapping(version = "1.2+") (3) 14 public Account getAccount1_2() { 15 } 16 17 @GetMapping(version = "1.5") (4) 18 public Account getAccount1_5() { 19 } 20}
| 1 | 모든 버전과 매칭 |
| 2 | 버전 1.1과 매칭 |
| 3 | 버전 1.2 및 그 이상과 매칭 |
| 4 | 버전 1.5와 매칭 |
버전 "1.3"인 요청의 경우:
버전 "1.5"인 요청의 경우:
버전 "1.6"인 요청은 매치가 없습니다. (1)과 (3)은 매칭되지만
엄격한 매치만 허용하는 (4)에 의해 대체되며, 따라서 매칭되지 않습니다.
이 시나리오에서는 NotAcceptableApiVersionException이 400 응답을 발생시킵니다.
위 내용은 요청 버전이 "supported" 버전이라고 가정한 것입니다. 그렇지 않으면 실패합니다.
API 버전 관리에 대한 기본 인프라 및 지원에 대한 자세한 내용은 API Versioning을 참조하십시오.
See equivalent in the Reactive stack
@GetMapping(및 @RequestMapping(method=HttpMethod.GET))은 요청 매핑에 대해
HTTP HEAD를 투명하게 지원합니다. 컨트롤러 메서드를 변경할 필요가 없습니다.
jakarta.servlet.http.HttpServlet에 적용된 응답 래퍼는 실제로 응답에
쓰지 않고도 Content-Length 헤더가 기록된 바이트 수로 설정되도록 보장합니다.
기본적으로 HTTP OPTIONS는 URL 패턴과 매칭되는 모든 @RequestMapping 메서드에
나열된 HTTP 메서드 목록으로 Allow 응답 헤더를 설정하여 처리됩니다.
HTTP 메서드 선언이 없는 @RequestMapping의 경우 Allow 헤더는
GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS로 설정됩니다. 컨트롤러 메서드는 항상
지원되는 HTTP 메서드를 선언해야 합니다(예: HTTP 메서드별 변형인
@GetMapping, @PostMapping 등을 사용).
@RequestMapping 메서드를 HTTP HEAD 및 HTTP OPTIONS에 명시적으로 매핑할 수 있지만,
일반적인 경우에는 필요하지 않습니다.
See equivalent in the Reactive stack
Spring MVC는 요청 매핑을 위해
composed annotations의
사용을 지원합니다. 이러한 어노테이션은 자체적으로 @RequestMapping으로 메타-어노테이션되어 있으며
더 좁고 구체적인 목적을 가진 @RequestMapping 속성의 일부(또는 전체)를 다시 선언하도록
구성됩니다.
@GetMapping, @PostMapping, @PutMapping, @DeleteMapping, @PatchMapping은
composed 어노테이션의 예입니다. 이 어노테이션은 대부분의
컨트롤러 메서드가 기본적으로 모든 HTTP 메서드에 매칭되는 @RequestMapping을 사용하는 것보다
특정 HTTP 메서드에 매핑되어야 한다는 이유로 제공됩니다.
composed 어노테이션을 구현하는 예가 필요하다면 이러한 어노테이션이 선언되는 방식을 살펴보십시오.
@RequestMapping은 동일한 요소(class, interface, 또는 method)에 선언된 다른@RequestMapping어노테이션과 함께 사용할 수 없습니다. 동일한 요소에서 여러 개의@RequestMapping어노테이션이 감지되면 경고가 로그에 기록되며 첫 번째 매핑만 사용됩니다. 이는@GetMapping,@PostMapping등과 같은 composed@RequestMapping어노테이션에도 적용됩니다.
Spring MVC는 커스텀 요청-매칭 로직을 가진 커스텀 요청-매핑
속성도 지원합니다. 이는 보다 고급 옵션으로, RequestMappingHandlerMapping을
서브클래싱하고 getCustomMethodCondition 메서드를 오버라이드해야 합니다.
여기에서
커스텀 속성을 확인하고 자체 RequestCondition을 반환할 수 있습니다.
See equivalent in the Reactive stack
핸들러 메서드를 프로그래밍 방식으로 등록할 수 있으며, 이를 사용하여 동적 등록을 수행하거나 서로 다른 URL 아래에서 동일한 핸들러 인스턴스를 사용하는 고급 케이스를 처리할 수 있습니다. 다음 예는 핸들러 메서드를 등록합니다:
1@Configuration 2public class MyConfig { 3 4 @Autowired 5 public void setHandlerMapping(RequestMappingHandlerMapping mapping, UserHandler handler) (1) 6 throws NoSuchMethodException { 7 8 RequestMappingInfo info = RequestMappingInfo 9 .paths("/user/{id}").methods(RequestMethod.GET).build(); (2) 10 11 Method method = UserHandler.class.getMethod("getUser", Long.class); (3) 12 13 mapping.registerMapping(info, handler, method); (4) 14 } 15}
| 1 | 대상 핸들러와 컨트롤러용 핸들러 매핑을 주입합니다. |
| 2 | 요청 매핑 메타데이터를 준비합니다. |
| 3 | 핸들러 메서드를 가져옵니다. |
| 4 | 등록을 추가합니다. |
1@Configuration 2class MyConfig { 3 4 @Autowired 5 fun setHandlerMapping(mapping: RequestMappingHandlerMapping, handler: UserHandler) { (1) 6 val info = RequestMappingInfo.paths("/user/{id}").methods(RequestMethod.GET).build() (2) 7 val method = UserHandler::class.java.getMethod("getUser", Long::class.java) (3) 8 mapping.registerMapping(info, handler, method) (4) 9 } 10}
| 1 | 대상 핸들러와 컨트롤러용 핸들러 매핑을 주입합니다. |
| 2 | 요청 매핑 메타데이터를 준비합니다. |
| 3 | 핸들러 메서드를 가져옵니다. |
| 4 | 등록을 추가합니다. |
@HttpExchangeSee equivalent in the Reactive stack
@HttpExchange의 주요 목적은 생성된 프록시로 HTTP 클라이언트 코드를 추상화하는 것이지만,
이러한 어노테이션이 배치되는 인터페이스는 클라이언트 대 서버 사용에 중립적인 계약입니다.
클라이언트 코드를 단순화하는 것 외에도 HTTP Service Client이 서버가 클라이언트 액세스를 위해 자신의 API를 노출하는 편리한 방법이 될 수 있는 경우도 있습니다.
이는 클라이언트와 서버 간의 결합도를 높이며, 특히 public API의 경우에는 종종 좋은 선택이 아니지만, internal API의 경우에는 정확히 목표가 될 수 있습니다.
이는 Spring Cloud에서 일반적으로 사용되는 접근 방식이며,
컨트롤러 클래스에서 서버 사이드 처리를 위해 @RequestMapping의 대안으로
@HttpExchange가 지원되는 이유입니다.
예:
1@HttpExchange("/persons") 2interface PersonService { 3 4 @GetExchange("/{id}") 5 Person getPerson(@PathVariable Long id); 6 7 @PostExchange 8 void add(@RequestBody Person person); 9} 10 11@RestController 12class PersonController implements PersonService { 13 14 public Person getPerson(@PathVariable Long id) { 15 // ... 16 } 17 18 @ResponseStatus(HttpStatus.CREATED) 19 public void add(@RequestBody Person person) { 20 // ... 21 } 22}
1@HttpExchange("/persons") 2interface PersonService { 3 4 @GetExchange("/{id}") 5 fun getPerson(@PathVariable id: Long): Person 6 7 @PostExchange 8 fun add(@RequestBody person: Person) 9} 10 11@RestController 12class PersonController : PersonService { 13 14 override fun getPerson(@PathVariable id: Long): Person { 15 // ... 16 } 17 18 @ResponseStatus(HttpStatus.CREATED) 19 override fun add(@RequestBody person: Person) { 20 // ... 21 } 22}
@HttpExchange와 @RequestMapping에는 차이점이 있습니다.
@RequestMapping은 경로 패턴, HTTP 메서드 등으로 여러 요청에 매핑할 수 있는 반면,
@HttpExchange는 구체적인 HTTP 메서드, 경로 및 콘텐츠 타입을 가진 단일 엔드포인트를 선언합니다.
메서드 파라미터 및 반환 값에 대해 일반적으로 @HttpExchange는
@RequestMapping이 지원하는 메서드 파라미터의 서브셋을 지원합니다.
특히 서버-사이드 전용 파라미터 타입은 제외합니다. 자세한 내용은
@HttpExchange 및
@RequestMapping에 대한
목록을 참조하십시오.
@HttpExchange는 또한 클라이언트 사이드에서 @RequestMapping(headers={})와 같이
"name=value" 형식의 pair를 받는 headers() 파라미터를 지원합니다. 서버 사이드에서는
@RequestMapping이
지원하는 전체 문법으로 확장됩니다.
Declaration
Handler Methods