RequestMapping
@RequestMapping("URL")
Spring Controller를 사용할 때 특정 URL 경로에 대해 요청이 들어오는 경우 메서드가 실행할 수 있게 끔 매핑해 줍니다.
/**
* RequestMapping에 별다른 method를 지정하지 않는 경우
* 모든 HttpMethod 허용
*
* 권장하지 않는 방식
*/
@RequestMapping("/request-mapping")
public String requestMapping() {
log.info("requestMapping 실행");
return "ok";
}
RequestMapping을 적용하고자 하는 메서드 위에 @RequestMapping 어노테이션을 기입해 주면 됩니다.
괄호 안의 "/request-mapping" 특정 URL에 대해 동작을 수행하도록 지정하는 것입니다.
❗️ 위와 같이 사용하는 방식은 권하지 않는 방식입니다.
단순히 @RequestMapping만 사용하는 경우 모든 HttpMethod에 대해 동작을 수행합니다.
예를 들어 개발자는 GET
메서드에 대해서만 호출이 되도록 의도했다고 가정해 보겠습니다.
그렇지만 별다른 제어가 없기 때문에 모든 HTTP Method에 대해 동작을 수행합니다.
@RequestMapping("URL", method = )
보통 API를 설계할 때에는 모든 HTTP Method에 대해서 고려하기보단 특정 HTTP Method에 대해서 설계를 진행합니다.
보다 상세한 통제를 하기 위해서 @RequestMapping에 method를 지정할 수 있습니다.
/**
* HttpMethod 중 GET 만 허용
*
* 그 외 다른 메서드가 호출되면 405 Method Not Allowed 응답.
*/
@RequestMapping(value = "/request-mapping/get", method = RequestMethod.GET)
public String requestMappingGet() {
log.info("requestMappingGet 실행");
return "ok";
}
이렇게 method를 직접 명시해 준 경우에는 다른 HTTP Method가 호출되었을 때 405 Status Code를 응답합니다.
HTTP 메서드 매핑 축약
매번 @RequestMapping("호출할 URL", method = {지정할 Method})
를 사용하는 경우 코드를 몇 자 더 쳐야 합니다.
이러한 귀찮음을 줄이기 위해 Spring은 다른 방식을 지원합니다.
@Slf4j
@RestController
public class HttpMethodMappingAbstract {
@GetMapping("/abstract/get-mapping")
public String getMapping() {
log.info("getMapping 실행");
return "ok";
}
@PutMapping("/abstract/put-mapping")
public String putMapping() {
log.info("putMapping 실행");
return "ok";
}
@DeleteMapping("/abstract/delete-mapping")
public String deleteMapping() {
log.info("deleteMapping 실행");
return "ok";
}
}
앞서 살펴본 예제들과 달리 @GetMapping, @PutMapping, @DeleteMapping 어노테이션을 사용하는 것을 확인할 수 있습니다.
사실 각 어노테이션들을 확인해 보면 @RequestMapping(method = )
이 구현되어 있습니다.
클래스 단위 RequestMapping, HTTP 메서드 매핑 축약 조합
위의 예제에서 URL의 경로에 공통적으로 "/abstract"가 들어가는 것을 확인할 수 있습니다.
이러한 경우 클래스 단위에서 @RequestMapping을 사용해 메서드에서 반복되는 경로의 입력을 줄일 수 있습니다.
@Slf4j
@RestController
@RequestMapping("/abstract2")
public class HttpMethodMappingAbstract2 {
@GetMapping("/get-mapping")
public String getMapping() {
log.info("getMapping 실행");
return "ok";
}
@PutMapping("/put-mapping")
public String putMapping() {
log.info("putMapping 실행");
return "ok";
}
@DeleteMapping("/delete-mapping")
public String deleteMapping() {
log.info("deleteMapping 실행");
return "ok";
}
}
공통되는 경로에 대해서는 Class위에 @RequestMapping을 사용해 경로를 지정해 줍니다.
이러한 경우 클래스의 @RequestMapping에 있는 URL과 메서드에 있는 URL이 결합됩니다.
- "abstract2" + "/get-mapping" -> "/abstract2/get-mapping"
- "abstract2" + "/put-mapping" -> "/abstract2/put-mapping"
- "abstract2" + "/delete-mapping" -> "/abstract2/delete-mapping"
PathVariable
특정 리소스를 조회할 때 리소스 경로에 식별자를 넣는 경우가 많습니다.
/uesrs/1
/books/game-of-thrones
Spring에서는 @PathVariable을 통해 값을 가져올 수 있습니다.
단일 PathVariable 조회
@GetMapping("/path-variable/{userId}")
public String singlePathVariable(@PathVariable String userId) {
log.info("userId = {}", userId);
return "userId = " + userId;
}
단일 PathVariable 조회의 경우 메서드의 파라미터에 @PathVariable을 사용하고 원하는 타입을 지정해 주면 됩니다.
✅ @GetMapping에 정의한 {} 안 단어와 동일하게 사용을 해야 값을 불러올 수 있습니다.
다중 PathVariable 조회
@GetMapping("/path-variable/users/{userId}/orders/{orderId}")
public String multiplePathVariable(@PathVariable String userId, @PathVariable String orderId) {
log.info("userId = {}, orderId = {}", userId, orderId);
return "userId = " + userId + " orderId = " + orderId;
}
다중 PathVariable 조회의 경우 메서드의 파라미터에 원하는 개수만큼 @PathVariable을 사용해 지정해 주면 됩니다.
HTTP Request Parameter
클라이언트가 서버에 데이터를 전달하는 경우 주로 3가지 방법을 사용합니다.
- GET
- 쿼리 파라미터
- /members?username=Tommy&age=30
- URL의 쿼리 파라미터에 데이터를 포함해서 전달하는 방식입니다.
- 쿼리 파라미터
- POST
- HTML FORM
- 메시지 바디에 쿼리파라미터 형식으로 전달합니다.
- username=Tommy&age=30
- HTML FORM
- Message Body
- HTTP API에서 주로 사용하는 방식
- JSON, XML, TEXT를 사용합니다.
- 데이터 형식은 주로 JSON을 사용합니다.
쿼리 파라미터
💡 GET 방식의 쿼리파라미터 방식과 HTML FORM으로 보내는 POST 방식 모두 쿼리파라미터 방식으로 전달됩니다.
HttpServletRequest
@GetMapping("/request-param/v1")
public String v1(HttpServletRequest request) {
String username = request.getParameter("username");
log.info("username = {}", username);
return "username = " + username;
}
HttpServletRequest에서 getParameter 메서드를 사용하면 쿼리파라미터 값을 읽어올 수 있습니다.
@RequestParam
Version 1
@RequestParam("파라미터 이름")
@GetMapping("/request-param/v2")
public String v2(@RequestParam("username") String username) {
log.info("username = {}", username);
return "username = " + username;
}
예를 들어 username이라는 파라미터값을 조회하고 싶을 때에는
@RequestParam("username")이라고 지정을 하고 갖고 오려고 하는 파라미터의 값 타입과 변수명을 붙여주면 됩니다.
Version 2
@RequestParam
@GetMapping("/request-param/v3")
public String v3(@RequestParam String username) {
log.info("username = {}", username);
return "username = " + username;
}
조회하고자 하는 쿼리 파라미터의 변수명과 Controller에서 사용하고자 하는 변수명이 같을 경우 다음과 같이 사용할 수 있습니다.
@ReqeustParam String username
Version 3
@RequestParam(required=false)
@GetMapping("/request-param/v4")
public String v4(@RequestParam(required = false) String username) {
log.info("username = {}", username);
return "username = " + username;
}
쿼리파라미터에 파라미터가 있어도 되고 없어도 된다면 required = false
를 넣어주면 됩니다.
만약 파라미터가 존재하지 않는다면 null이 할당됩니다.
❗️ required = false 옵션을 사용할 경우 primitive type은 null을 가질 수 없으므로 사용하면 안 됩니다.
💡 대신 래퍼 클래스들을 사용해 주면 됩니다.
Version 4
@RequestParam(defaultValue=)
@GetMapping("/request-param/v5")
public String v5(@RequestParam(defaultValue = "default NickName") String username) {
log.info("username = {}", username);
return "username = " + username;
}
쿼리파라미터에 파라미터가 존재하지 않을 때 기본 값을 할당하고 싶다면 defaultValue=
를 사용하면 됩니다.
@ModelAttribute
@PostMapping("/model-attribute")
public Member modelAttribute(@ModelAttribute Member member) {
return member;
}
---
@Data
public class Member {
private String username;
private Integer age;
}
SpringMVC는 쿼리파라미터를 사용해 객체를 바로 받아올 수도 있습니다.
@ModelAttribute가 존재하는 경우 다음과 같이 실행됩니다.
- Member 객체를 생성
- 파라미터 이름으로 Member 객체의 프로퍼티를 찾는다.
- setter를 호출해 파라미터의 값을 바인딩.
MessageBody
@PostMapping("request-body")
public String requestBody(@RequestBody String messageBody) {
log.info("message Body = {}", messageBody);
return messageBody;
}
JSON으로 데이터를 요청받는 경우 @RequestBody를 사용해 받아올 수 있습니다.
출처 : 김영한 - Spring MVC 1편
'Spring' 카테고리의 다른 글
[Spring] @Retryable, Event 적용기 (1) | 2023.12.04 |
---|---|
Spring, 그리고 Test (4) | 2023.10.11 |
Junit에서 TestInstance의 생명주기 (0) | 2023.07.03 |
NamedParameterJdbcTemplate (0) | 2023.07.01 |
JdbcTemplate 사용 방법에 대해서 (0) | 2023.07.01 |