Spring에서 컨트롤러를 지정해주기 위한 어노테이션은 @Controller와 @RestController가 있다.
두 가지의 차이점은 나중에 다루기로 하고, 우선은 "Spring에서 사용하는 컨트롤러에는 저 두 어노테이션 중 하나를 붙여야한다~"만 이해하고 넘어가도록 하자.
스프링에서 controller에 request를 매핑하기 위해 사용하는 가장 기본 방법은 바로 @RequestMapping
어노테이션을 달아주는 것이다.
@RestController
public class MappingController {
@RequestMapping("/hello-basic")
public String helloBasic() {
return "ok";
}
}
이런식으로 작성하면, "/hello-basic" 이라는 URL로 호출이 왔을 때 이 메서드가 실행된다.
@RequestMapping
@RequestMapping 에 method 속성으로 HTTP 메서드를 지정하지 않으면 HTTP 메서드와 무관하게 호출된다. 즉, 모든 HTTP 메서드 허용를 허용한다. (GET, HEAD, POST, PUT, PATCH, DELETE)
@RequestMapping(value = "/mapping-get-v1", method = RequestMethod.GET)
public String mappingGetV1() {
return "ok";
}
만약 특정 HTTP 메소드만 허용하고 싶다면 method 속성을 걸어주면 된다.
만약 여기에 POST 요청을 하면 405에러(Method Not Allowed)가 뜬다.
하지만 기본 @RequestMapping보다는 HTTP 메서드를 축약한 애노테이션을 사용하는 것이 더 직관적이다.
// 사용 예시
@GetMapping(value = "/mapping-get-v2")
public String mappingGetV2() {
return "ok";
}
// @GetMapping 내부 코드 (@RequestMapping 과 method 를 지정)
@RequestMapping(method = RequestMethod.GET)
public @interface GetMapping {...}
@RequestMapping은 URI pattern을 통해 매핑될 수 있다.
최근 HTTP API는 다음과 같이 리소스 경로에 식별자를 넣는 스타일을 선호한다.
"/mapping/userA"
"/users/1"
@RequestMapping 은 URL 경로를 템플릿화 할 수 있는데, @PathVariable
을 사용하면 매칭 되는 부분을 편리하게 조회할 수 있다.
@GetMapping("/mapping/{userId}")
public String mappingPath(@PathVariable("userId") String data) {
return "ok";
}
@GetMapping("/mapping/users/{userId}/orders/{orderId}")
public String mappingPath(@PathVariable String userId, @PathVariable Long orderId) {
return "ok";
}
?
는 경로에서 한 글자는 어떤 글자가 와도 된다.
여기서는 ima와 e.png 사이에 글자 하나가 아무거나 들어와도 상관이 없다.
@GetMapping("/resources/ima?e.png")
*
은 경로 사이에 0개 이상의 문자열과 일치하면 된다.
여기서는 뒤에가 .png로만 끝나면 상관이 없다.
@GetMapping("/resources/*.png")
**
은 무엇이 들어와도 된다.
여기서는 Resources/ 뒤에 어떤 내용이 들어와도 해당 경로로 매핑이 된다.
(좀 더 상세하게 매핑된 내용이 있다면 해당 메서드로 빠진다.)
@GetMapping("/resources/**")
특정 파라미터가 있거나 없는 조건을 추가할 수 있다. 잘 사용하지는 않는다.
@GetMapping(value = "/mapping-param", params = "mode=debug")
public String mappingParam() {
return "ok";
}
** 예시 **
params="mode"
params="!mode"
params="mode=debug"
params="mode!=debug"
params = {"mode=debug","data=good"}
특정 헤더가 있거나 없는 조건을 추가할 수 있다. 잘 사용하지는 않는다.
@GetMapping(value = "/mapping-header", headers = "mode=debug")
public String mappingHeader() {
return "ok";
}
** 예시 **
headers="mode"
headers="!mode"
headers="mode=debug"
headers="mode!=debug"
HTTP 요청의 Content-Type 헤더를 기반으로 미디어 타입으로 매핑한다.
만약 맞지 않으면 HTTP 415 상태코드(Unsupported Media Type)을 반환한다.
@PostMapping(value = "/mapping-consume", consumes = "application/json")
public String mappingConsumes() {
return "ok";
}
** 예시 **
consumes="application/json"
consumes="!application/json"
consumes="application/*"
consumes="*\/*"
consumes=MediaType.APPLICATION_JSON_VALUE
consumes = {"text/plain", "application/*"}
HTTP 요청의 Accept 헤더를 기반으로 미디어 타입으로 매핑한다. 만약 맞지 않으면 HTTP 406 상태코드(Not Acceptable)을 반환한다.
@PostMapping(value = "/mapping-produce", produces = "text/html")
public String mappingProduces() {
return "ok";
}
** 예시 **
produces = "text/html"
produces = "!text/html"
produces = "text/*"
produces = "*\/*"
produces = "text/plain"
produces = {"text/plain", "application/*"}
produces = MediaType.TEXT_PLAIN_VALUE
produces = "text/plain;charset=UTF-8"
참고
인프런 김영한님의 스프링 MVC 1편의 [섹션6 - Spring MVC 기본기능]
Spring 공식문서의 Request Mapping, URI pattern, Parameters, Headers, Media Types