요청 매핑
코드를 보기 전에 기본 지식으로, @RestController 에노테이션이 붙어 있는 클래스는 반환 객체가 응답 HTML로 렌더링 된다는 걸 까먹지 말자.
자세한 설명은 주석으로 확인하자 !
package hello.springmvc.basic.requestmapping;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
@RestController
public class MappingController {
private Logger log = LoggerFactory.getLogger(getClass());
// @RequestMapping의 HTTP 메서드 옵션을 비워두면 모든 요청을 다 받을 수 있다.
@RequestMapping("/hello-basic")
public String helloBasic() {
log.info("helloBasic");
return "ok";
}
/**
* method 특정 HTTP 메서드 요청만 허용
* GET, HEAD, POST, PUT, PATCH, DELETE
*/
@RequestMapping(value = "/mapping-get-v1", method = RequestMethod.GET)
public String mappingGetV1() {
log.info("mappingGetV1");
return "ok";
}
/**
* @RequestMapping 의 HTTP 메서드 옵션을 빼고 축약하여 사용 가능한 메서드
* 하지만 내부를 까보면 다 @ReqeustMapping 을 가지고 있다.
* @GetMapping
* @PostMapping
* @PutMapping
* @DeleteMapping
* @PatchMapping
*
* 만약 아래 Get요청 메서드에 Post 를 날리면 405 (Method not allowed) 상태 코드 반환
*/
@GetMapping("/mapping-get-v2")
public String mappingGetV2() {
log.info("mapping-get-v2");
return "ok";
}
/**
* PathVariable 사용
* 변수명이 같으면 생략 가능
*
* @PathVariable("userId") String userId -> @PathVariable String userId
* 예를 들어 URL 자체에 값이 넘어온다 -> /mapping/userA
*/
@GetMapping("/mapping/{userId}")
public String mappingPath(@PathVariable("userId") String data) {
log.info("mappingPath userID={}", data);
return "ok";
}
/**
* 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";
}
/**
* 파라미터로 추가 매핑
* 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";
}
/**
* 특정 헤더로 추가 매핑
* headers="mode",
* headers="!mode"
* headers="mode=debug"
* headers="mode!=debug" (! = )
*/
@GetMapping(value = "/mapping-header", headers = "mode=debug")
public String mappingHeader() {
log.info("mappingHeader");
return "ok";
}
/**
* 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";
}
/**
* 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";
}
}
요청 매핑 API
회원 관리 API를 예시로 작성해보자.
회원 관리 API 설계 예시
회원 목록 조회 | GET /users |
회원 등록 | POST /users |
회원 조회 | GET /users/{userId} |
회원 수정 | PATCH /users/{userId} |
회원 삭제 | DELETE /users/{userId} |
package hello.springmvc.basic.requestmapping;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/mapping/users")
public class MappingClassController {
@GetMapping
public String user() {
return "get users";
}
@PostMapping
public String addUser() {
return "post user";
}
@GetMapping("/{userId}")
public String findUser(@PathVariable String userId) {
return "get userId=" + userId;
}
@PatchMapping("/{userId}")
public String updateUser(@PathVariable String userId) {
return "update userId=" + userId;
}
@DeleteMapping("/{userId}")
public String deleteUser(@PathVariable String userId) {
return "delete userId=" + userId;
}
}
자세히 보면 user() 메서드와 addUser() 메서드는 같은 URL을 공유한다. 이런게 가능할까?
당연히 가능하다. 우리는 두 경로에 다른 HTTP 메서드를 매핑 했기 때문에 같은 URL이어도 HTTP 요청에 따라 구분이 가능해진다.
'Spring > MVC' 카테고리의 다른 글
[Spring] 메시지와 국제화 - 어떻게 국제화가 자동으로 일어날까요? (0) | 2025.07.03 |
---|---|
[Spring] @ModelAndAttribute 의 동작 과정 (0) | 2025.06.24 |
[Spring] Spring MVC - 스프링이 제공하는 컨트롤러 (0) | 2025.06.23 |
[Spring] 내가 만든 MVC 와 Spring MVC 차이 (1) | 2025.06.23 |
[Spring] FrontController V5(完) - 다양한 인터페이스 구현체 처리하기 (2) | 2025.06.23 |