3 분 소요

인프런 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술편을 학습하고 정리한 내용 입니다.

요청이 왔을 때 어떤 메서드를 연결 할지 에 대한 걸 알아보자

hello.springmvc.basic.requestmapping.MappingController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RestController  
public class MappingController {  
  
    private final Logger log = LoggerFactory.getLogger(getClass());  
  
    /**  
     * 기본 요청  
     * 둘다 허용 : /hello-basic, /hello-basic/  
     * HTTP 메서드 모두 허용 : GET, POST, HEAD, PUT, PATCH, DELETE  
     * */    
    @RequestMapping("/hello-basic")  
    public String helloBasic() {  
        log.info("helloBasic");  
        return "ok";  
    }  
}

매핑 정보

  • @RestController
    • @Controller는 반환 값이 String이면 뷰 이름으로 인식된다. 그래서 뷰를 찾고 뷰가 랜더링 된다.
    • @RestController는 반환 값으로 뷰를 찾는 것이 아니라, HTTP 메시지 바디에 바로 입력한다. 따서 실행 결과로 ok 메시지를 받을 수 있다. @ResponseBody와 연관이 있는데, 다음에 더 자세히 알아보자.
  • @RequestMapping("/hello-basic")
    • /hello-basicURL 요청이 오면 이 메서드가 실행 되도록 매핑한다.
    • 대부분의 속성을 배열 []로 제공하므로 다중 설정이 가능하다. {"/hello-basic", "/hello-go"} 뭐 이런식으로

둘다 허용 다음 두 가지 요청은 다른 URL 이지만, 스프링은 다음 URL 요청을 같은 요청으로 매핑한다.

  • 매핑 : /hello-basic
  • URL 요청 : /hello-basic, /hello-basic/

❗❗스프링 부트 3.0 이후❗❗
스프링 부트 3.0 부터는 /hello-basic, /hello-basic/은 서로 다른 URL 요청을 사용해야 한다.
기존에는 마지막에 있는 /슬래시를 제거했지만, 스프링 부트 3.0부터는 마지막 슬래시를 유지한다.
따라서 다음과 같이 다르게 매핑해서 사용해야 한다.
매핑 : /hello-basic → URL 요청 : /hello-basic
매핑 : /hello-basic/ → URL 요청 : /hello-basic/

HTTP 메서드 매핑 축약

1
2
3
4
5
6
7
8
9
10
11
12
13
/**  
 * 편리한 축약 애노테이션  
 * @GetMapping  
 * @PostMapping  
 * @PutMapping  
 * @DeleteMapping  
 * @PatchMapping  
 */  
@GetMapping(value = "/mapping-get-v2")  
public String mappingGetV2() {  
    log.info("mapping-get-v2");  
    return "ok";  
}

HTTP 메서드를 축약한 애노테이션을 사용하는 것이 더 직관적이다. 코드를 보면 내부에서 @RequestMappingmethod를 지정해서 사용하는 걸 확인할 수 있다.

getMapping에 post 요청하니 405 에러가 나온다.

PathVariable (경로 변수) 사용

1
2
3
4
5
6
7
8
9
10
/**  
 * PathVariable 사용  
 * 변수명이 같으면 생략 가능  
 * @PathVariable("userId") String userId -> @PathVariable String userId  
 */
@GetMapping("/mapping/{userId}")  
public String mappingPath(@PathVariable("userId") String data) {  
    log.info("mappingPath userId = {}", data);  
    return "ok";  
}

최근 HTTP API는 다음과 같이 리소스 경로에 식별자를 넣는 스타일을 선호한다.

  • /mapping/userA
  • /users/1

  • @RequestMapping은 URL 경로를 템플릿화 할 수 있는데, @PathVariable을 사용하면 매칭 되는 부분을 편리하게 조회할 수 있다.
  • @PathVariable의 이름과 파라미터 이름이 같으면 생략할 수 있다.

PathVariable - 다중 사용

1
2
3
4
5
6
@GetMapping("/mapping/users/{userId}/orders/{orderId}")  
public String mappingPath(@PathVariable("userId") String userId, @PathVariable("orderId") Long  
        orderId) {  
    log.info("mappingPath userId = {}, orderId = {}", userId, orderId);  
    return "ok";  
}

다음과 같이 매핑을 {}/{} 여러개 할 수 도 있다.

참고

1
2
3
4
5
6
7
8
/**  
 * PathVariable 사용 다중  
 */  
@GetMapping("/mapping/users/{userId}/orders/{orderId}")  
public String mappingPath(@PathVariable String userId, @PathVariable Long orderId) {  
    log.info("mappingPath userId = {}, orderId = {}", userId, orderId);  
    return "ok";  
}

스프링 부트 3.2부터 자바 컴파일러에 -parameters 옵션을 넣어주어야 어노테이션의 이름을 생략할 수 있다. 주로

@RequestParam, @PathVariable, @Autowired, @ConfigurationProperties
에노테이션 사용 시 오류 발생 가능

특정 파라미터 조건 매핑 (자주 사용 X)

1
2
3
4
5
6
7
8
9
10
11
12
/**  
 * 파라미터로 추가 매핑  
 * params="mode",  
 * params="!mode" * params="mode=debug" 
 * params="mode!=debug" (! = ) 
 * params = {"mode=debug","data=good"} 
 * */
@GetMapping(value = "/mapping-param", params = "mode=debug")  
public String mappingParam() {  
    log.info("mappingParam");  
    return "ok";  
}

이런 식이다.

1
2
3
4
5
@GetMapping(value = "/mapping-header", headers = "mode=debug")  
public String mappingHeader() {  
    log.info("mappingParam");  
    return "ok";  
}

이런 식으로 헤더도 가능하다.

미디어 타입 조건 매핑 - HTTP 요청 Content-Type, consume

컨텐츠 타입에 따라 처리하고 싶으면 다음과 같이 사용할 수 있다.

이럴 땐 consumes= 를 사용해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
/**  
 * Content-Type 헤더 기반 추가 매핑 Media Type  
 * consumes="application/json" 
 * consumes="!application/json" 
 * consumes="application/*" 
 * consumes="*\/*" 
 * MediaType.APPLICATION_JSON_VALUE 
 * */
@PostMapping(value = "/mapping-consume", consumes = "application/json")  
public String mappingConsumes() {  
    log.info("mappingConsumes");  
    return "ok";  
}

미디어 타입 조건 매핑 - HTTP 요청 Accept, produce

1
2
3
4
5
6
7
8
9
10
11
12
/**  
 * Accept 헤더 기반 Media Type  
 * produces = "text/html" 
 * produces = "!text/html" 
 * produces = "text/*" 
 * produces = "*\/*" 
 * */
@PostMapping(value = "/mapping-produce", produces = "text/html")  
public String mappingProduces() {  
    log.info("mappingProduces");  
    return "ok";  
}

Accept 헤더 기반 Media Type 으로 구분 가능하다.

만약 맞지 않으면 406 상태 코드(Not Acceptable)을 반환한다.

예시)

1
2
3
4
produces = "text/plain" 
produces = {"text/plain", "application/*"} 
produces = MediaType.TEXT_PLAIN_VALUE 
produces = "text/plain;charset=UTF-8"

태그:

카테고리:

업데이트:

댓글남기기