일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 소수
- Spring
- brute force
- 파이썬
- spring security
- error
- 탐욕법
- 최단경로
- 라이브템플릿
- 프로그래머스
- 코딩테스트
- java
- springboot
- 2981
- BFS
- 문자열
- 백준
- applicationeventpublisher
- javascript
- Python
- 2018 KAKAO BLIND RECRUITMENT
- counting elements
- Greedy
- HTTP
- beandefinitionstoreexception
- 알고리즘
- algorithm
- API
- Dijkstra
- codility
- Today
- Total
Altiora Petamus
다양한 HTTP Mapping 2 본문
Intro
REST API 의 다양한 사용법에 대해 알아봅니다.
모든 테스트는 Postman 을 활용해 진행했습니다.
HTTP Request
기본 사용법
@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;
}
}
@RequestMapping 을 클래스 레벨에 매핑 정보를 작성하면 모든 메서드에 해당 경로가 조합되어 적용됩니다. url 경로의 중복을 제거하는 방법으로 사용할 수 있습니다.
header 조회
@Slf4j
@RestController
public class RequestHeaderController {
@RequestMapping(value = "/headers")
public String headers(HttpServletRequest request,
HttpServletResponse response,
HttpMethod httpMethod,
Locale locale,
@RequestHeader MultiValueMap<String, String> headerMap,
@RequestHeader("host") String host,
@CookieValue(value = "myCookie", required = false) String cookie) {
log.info("request = {}", request);
log.info("response = {}", response);
log.info("httpMethod = {}", httpMethod);
log.info("locale = {}", locale);
log.info("headerMap = {}", headerMap);
log.info("host = {}", host);
log.info("cookie = {}", cookie);
return "ok";
}
}
HttpServletRequest
HttpServletResponse
HttpMethod
: Http method 를 조회합니다.
Locale
: Locale 정보를 조회합니다.
@RequestHeader MultiValueMap<String, String>
: 모든 헤더를 MultiValueMap 형식으로 조회합니다.
@RequestHeader("host") String host
: 특정 HTTP 헤더를 조회합니다.
@CookieValue(value = "myCookie", required = false) String cookie
: 특정 쿠키를 조회합니다.
필수 값 여부 : require
기본 값 : defaultValue
Parameter 조회
파라미터를 조회할 땐 다음 3가지 방식으로 조회할 수 있습니다.
- GET - 쿼리 파라미터
- /url?username=hello&age=20
- 메시지 바디 없이, URL의 쿼리 파라미터에 데이터를 포함해서 전달
- 예) 검색, 필터, 페이징등에서 많이 사용하는 방식
- POST - HTML Form
- content-type: application/x-www-form-urlencoded
- 메시지 바디에 쿼리 파리미터 형식으로 전달 username=hello&age=20
- 예) 회원 가입, 상품 주문, HTML Form 사용
- HTTP message body에 데이터를 직접 담아서 요청
- HTTP API에서 주로 사용, JSON, XML, TEXT
- 데이터 형식은 주로 JSON 사용
- POST, PUT, PATCH
이 중 GET, POST 는 전송 형식이 같으므로 구분없이 조회할 수 있습니다.
하나씩 알아봅니다.
Request parameter 조회
HttpServletRequest - V1
@Slf4j
@Controller
public class RequestParamController {
@RequestMapping("/request-param-v1")
public void requestParamV1(HttpServletRequest request, HttpServletResponse response) throws IOException {
String username = request.getParameter("username");
int age = Integer.parseInt(request.getParameter("age"));
log.info("username = {}, age = {}", username, age);
response.getWriter().write("ok");
}
}
request.getParameter()
를 사용하여 요청으로 들어오는 파라미터 값을 조회할 수 있습니다.
@RequestParam - V2
@ResponseBody
@RequestMapping("/request-param-v2")
public String requestParamV2(
@RequestParam("username") String memberName,
@RequestParam("age") int memberAge) {
log.info("memberName = {}, age = {}", memberName, memberAge);
return "ok";
}
@RequestParam
: 파라미터값을 아주 편리하게 조회할 수 있습니다.
@ResponseBody
: view 조회를 무시하고 값을 직접 HTTP message body 에 입력합니다. 추후에 나오는 @RestController
와 관련이 있습니다.
@RequestParam - V3
@ResponseBody
@RequestMapping("/request-param-v3")
public String requestParamV3(
@RequestParam String username,
@RequestParam int age) {
log.info("username = {}, age = {}", username, age);
return "ok";
}
@RequestParam
의 이름이 변수명과 같다면 생략 가능합니다.
@RequestParam 의 생략 - V4
@ResponseBody
@RequestMapping("/request-param-v4")
public String requestParamV4(
String username,
int age) {
log.info("username = {}, age = {}", username, age);
return "ok";
}
만약 변수의 타입이 String
, int
, Integer
등의 단순 타입이면 @RequestParam
도 생략 가능합니다!
@RequestParam 을 생략하면 스프링 내부적으로 required = false 를 적용합니다.
⚠️너무 과한 생략은 가독성을 해칠 수 있으므로 충분한 합의가 있을 경우에 사용합시다!
파라미터의 필수 여부
@ResponseBody
@RequestMapping("/request-param-v5")
public String requestParamRequired(
@RequestParam(required = true) String username,
@RequestParam(required = false) Integer age) {
log.info("username = {}, age = {}", username, age);
return "ok";
}
required = true 가 기본값으로 설정되어 있으며 요청시 파라미터가 넘어오지 않는다면 400 예외를 발생시킵니다. false 로 설정하게 될 경우, 값이 넘어오지 않으면 null
값이 세팅되는데 int
타입은 null
일 수 없으므로 Integer
로 바꿔줍니다.
⚠️빈 문자("")는 null 이 아님을 주의합니다!
파라미터의 기본값 설정
@ResponseBody
@RequestMapping("/request-param-default")
public String requestParamDefault(
@RequestParam(defaultValue = "guest") String username,
@RequestParam(defaultValue = "-1") int age) {
log.info("username = {}, age = {}", username, age);
return "ok";
}
파라미터가 없을 때 설정한 값을 넣어줍니다. 이 때 파라미터에는 무조건 값이 설정되므로 required = false 로 세팅해도 동작하지 않습니다. 또 "" 의 경우에도 기본값을 넣어줍니다.
파라미터를 맵으로 조회
@ResponseBody
@RequestMapping("/request-param-map")
public String requestParamMap(
@RequestParam Map<String, Object> paramMap) {
log.info("username = {}, age = {}", paramMap.get("username"), paramMap.get("age"));
return "ok";
}
파라미터의 값이 하나가 확실하다면 Map
을 사용해도 되지만, 그렇지 않다면 MultiValueMap
을 사용하면 됩니다. 하지만 대부분 파라미터는 1개이므로 필요할 때 사용합시다.
@ModelAttribute 의 사용
실제 개발을 할 때면 파라미터를 받아서 객체를 생성해야할 경우가 있습니다. 다음과 같이 말이죠.
@RequestParam String username;
@RequestParam int age;
HelloData data = new HelloData();
data.setUsername(username);
data.setAge(age);
스프링은 이 과정을 완전히 자동화 해주는 @ModelAttribute
기능을 제공합니다.
먼저 요청 파라미터를 바인딩 받을 객체를 만듭니다.
package hello.springmvc.basic;
import lombok.Data;
@Data
public class HelloData {
private String username;
private int age;
}
@ModelAttribute 적용
@ResponseBody
@RequestMapping("/model-attribute-v1")
public String modelAttributeV1(@ModelAttribute HelloData helloData) {
log.info("helloData = {}", helloData);
return "ok";
}
Spring MVC 는 @ModelAttribute
가 있으면 다음을 실행합니다.
HelloData
객체를 생성- 요청 파라미터의 이름으로
HelloData
객체의 프로퍼티를 찾는다. 그리고 해당 프로퍼티의setter
를 호출해서 파라미터의 값을 입력(바인딩).
@ModelAttribute 의 생략
@ResponseBody
@RequestMapping("/model-attribute-v2")
public String modelAttributeV2(HelloData helloData) {
log.info("helloData = {}", helloData);
return "ok";
}
@ModelAttribute
는 생략할 수 있습니다. 그런데 위에서 살펴본 바와 같이 @RequestParam
도 생략할 수 있으니 뭐가 적용될 지 혼란이 발생할 수 있습니다. 스프링은 해당 생략시 다음과 같은 규칙을 적용합니다.
String
,int
,Integer
등 단순 타입 ⇒@RequestParam
- 그 외 Reference Type ⇒
@ModelAttribute
(argument resolver 로 지정해둔 타입 제외)
'Java > Spring Framework' 카테고리의 다른 글
@JsonNaming 사용 (springboot 2.5.3 ~) (0) | 2021.08.04 |
---|---|
다양한 HTTP Mapping 1 (0) | 2021.07.28 |
in-memory DB 구현 (0) | 2021.06.30 |
Spring Security 사용하기 1 (0) | 2021.06.26 |
Spring Security란? (0) | 2021.06.19 |