yeon's blog
[Spring] HTTP 요청 매핑 및 API 예시 본문
HTTP 요청 매핑 관련 애노테이션을 정리해보자 ‼️
요청 매핑
@RequestMapping
클라이언트 요청에 정보를 어떤 Controller가 처리할지 매핑하기 위한 애노테이션
@RequestMapping에 URL을 포함하여 해당 Controller 클래스에 명시하여 사용한다.
웹 브라우저에서 해당 URL이 호출되면 Controller 내부의 메서드가 호출된다.
@RequestMapping("/mapping/users")
public class MappingClassController {
...
}
웹 브라우저에서 `http://localhost:8080/mapping/users` URL이 호출되면
→ MappingClassController 내부의 메서드가 호출된다는 것이다.
@Controller
@Controller 애노테이션 내부에 @Component 애노테이션이 포함되어 있어 컴포넌트 스캔의 대상이 되기 때문에, 스프링이 자동으로 스프링 빈으로 등록한다.
Spring MVC에서 애노테이션 기반 컨트롤러로 인식하게 된다.
@Controller
public class MappingClassController {
...
}
@RestController
@RestController 애노테이션 내부에 @Component 애노테이션이 포함되어 있어 컴포넌트 스캔의 대상이 되기 때문에, 스프링이 자동으로 스프링 빈으로 등록한다.
Spring MVC에서 애노테이션 기반 컨트롤러로 인식하게 된다.
@RestController
public class MappingClassController {
...
}
위의 두 애노테이션은 차이점이 존재한다 ‼️
- @Controller: 반환 값이 String이면 뷰 이름으로 인식 → 뷰를 찾고 뷰가 렌더링 됨
- @RestController: 반환 값으로 뷰를 찾는 것이 아니라, HTTP 메시지 바디에 바로 입력
@RequestMapping과 @Controller
스프링 빈 중에서 @RequestMapping이 있으면 핸들러 매핑을 조회할 때 RequestMappingHandlerMapping이 실행된다.RequestMappingHandlerMapping은 스프링빈 중에서 클래스 레벨에 @RequestMapping 또는 @Controller가 붙어있는경우 매핑 정보로 인식한다.
@Controller
public class MappingClassController {
...
}
HTTP 메서드 매핑
@RequestMapping은 URL뿐만 아니라, HTTP 메서드도 함께 설정할 수 있다.
ex. GET 메서드를 이용해야 하는 경우 다음과 같이 작성하면 된다.
/**
* method 특정 HTTP 메서드 요청만 허용
* GET, POST, PUT, PATCH, DELETE
* */
@RequestMapping(value = "/mapping-get-v1", method = RequestMethod.GET)
public String mappingGetV1() {
log.info("mappingGetV1");
return "ok";
}
주석에 써있는 것처럼 GET 뿐만 아니라 POST, PUT, PATCH, DELETE 모두 가능하다.
위와 같이 method = RequestMethod.GET을 이용할 수도 있지만, 더욱 편리하게 사용할 수 있도록 현재는 축약해서 사용한다.
HTTP 메서드 매핑 축약
@GetMapping("/mapping-get")
public String mappingGet() {
return "ok";
}
@PostMapping("/mapping-post")
public String mappingPost() {
return "ok";
}
@PutMapping("/mapping-put")
public String mappingPut() {
return "ok";
}
@DeleteMapping("/mapping-delete")
public String mappingDelete() {
return "ok";
}
@PatchMapping("/mapping-patch")
public String mappingPatch() {
return "ok";
}
@RequestMapping 다중 경로
추가로, @RequestMapping은 url을 아래와 같이 배열 형태로 작성하여 다중 설정이 가능하다.
@RestController
public class MappingController {
private Logger log = LoggerFactory.getLogger(getClass());
// 다중 설정
@RequestMapping({"/hello-basic", "/hello-go"})
public String helloBasic() {
log.info("helloBasic");
return "ok";
}
}
위와 같은 코드를 실행하면 두 가지 경로 모두 이용이 가능한 것이다.
- http://localhost:8080/hello-basic
- http://localhost:8080/hello-go
PathVariable(경로 변수) 사용
/**
* 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";
}
만약, 변수명이 경로명과 같으면 @PathVariable의 속성은 생략이 가능하다.
/**
* PathVariable 사용
* 변수명이 같으면 생략 가능
* @PathVariable("userId") String userId -> @PathVariable String userId
*/
@GetMapping("/mapping/{userId}")
public String mappingPath(@PathVariable String userId) {
log.info("mappingPath userId={}", data);
return "ok";
}
PathVariable 사용 - 다중
경로 변수는 다중으로 사용이 가능하다.
/**
* 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";
}
미디어 타입 조건 매핑
Consume
consumes를 통해 HTTP 요청 시 미디어 타입 조건을 매핑할 수 있다.
Content-Type에 따라 분리하여 매핑할 수 있다.
/**
* Content-Type 헤더 기반 추가 매핑 Media Type * consumes="application/json"
* consumes="!application/json"
* consumes="application/*"
* consumes="*\/*"
* MediaType.APPLICATION_JSON_VALUE
*/
@PostMapping(value = "/mapping-consume", consumes = MediaType.APPLICATION_JSON_VALUE)
public String mappingConsumes() {
log.info("mappingConsumes");
return "ok";
}
HTTP 요청의 Content-Type 헤더를 기반으로 미디어 타입으로 매핑한다.
만약 맞지 않으면 HTTP 415 상태코드(Unsupported Media Type)을 반환한다.
Accept, produce
헤더의 Accept 헤더를 기반의 미디어 타입으로 매핑한다.
/**
* Accept 헤더 기반 Media Type * produces = "text/html"
* produces = "!text/html" * produces = "text/*"
* produces = "*\/*"
*/
@PostMapping(value = "/mapping-produce", produces = MediaType.TEXT_HTML_VALUE)
public String mappingProduces() {
log.info("mappingProduces");
return "ok";
}
HTTP 요청의 Accept 헤더를 기반으로 미디어 타입으로 매핑한다.
만약 맞지 않으면 HTTP 406 상태코드(Not Acceptable)을 반환한다.
요청 매핑 - API 예시
회원 관리 API
회원 목록 조회: GET `/users`
회원 등록: POST `/users`
회원 조회: GET `/users/{userId}`
회원 수정: PATCH `/users/{userId}`
회원 삭제: DELETE `/users/{userId}`
MappingClassController 전체코드
package hello.springmvc.basic.requestmapping;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/mapping/users")
public class MappingClassController {
@GetMapping
public String users() {
return "get users";
}
@PostMapping
public String addUser() {
return "post users";
}
@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;
}
}
'Spring > Spring 개념' 카테고리의 다른 글
[Spring] HTTP 요청 파라미터 - 쿼리 파라미터, HTML Form, @RequestParam, @ModelAttribute (1) | 2024.01.14 |
---|---|
[Spring] HTTP 요청 - 기본, 헤더 정보 조회 (1) | 2024.01.14 |
[Spring] 로그(Log)와 로깅 프레임워크(Logging Framework) (2) | 2024.01.13 |
[Spring] Spring Security 처리 과정 (0) | 2023.12.12 |
[Spring] Spring Security 개념 (0) | 2023.12.12 |