인프런 김영한 님의 스프링 강의이며, 섹션 6 - 스프링 MVC 기본 기능을 정리하는 시간이다.
자세한 설명이 궁금하면 수강을 권장한다.
HTTP 요청 - 기본, 헤더 조회
애노테이션 기반의 스프링 컨트롤러는 다양한 파라미터를 지원한다.
@Slf4j
@RestController
public class RequestHeaderController {
@RequestMapping("/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("header host={}", host);
log.info("myCookie={}", cookie);
return "ok";
}
}
HttpMethod : HTTP 메서드를 조회
Locale : locale 정보를 조회
@RequestHeader MultiValueMap<String, String> headerMap : 모든 HTTP 헤더를 MultiValueMap 형식으로 조회
@RequestHeader(key) : 특정 HTTP 헤더를 조회
@CookieValue(key) : 특정 쿠키를 조회
참고 : MultiValueMap는 하나의 키에 여러 값을 받을 수 있는 Map이다.
스프링 컨트롤러의 다양한 파라미터와 응답 목록은 가이드를 참고하자.
https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-arguments
https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-return-types
HTTP 요청 파라미터 - 쿼리 파라미터, HTML Form
HTTP 요청 데이터 조회 - 개요
이전 서블릿에서 HTTP 요청 데이터를 조회 방법을 스프링이 얼마나 깔끔하게 해 주는지 알아보자.
// 서블릿 방식
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
System.out.println("username = " + username);
...
}
클라이언트에서 서버로 요청 데이터를 전달할 때는 3가지 방법을 사용
1. GET - 쿼리 파라미터
- /url?username=hello&age=20
- 메시지 바디 없이, URL의 쿼리 파라미터에 데이터를 포함해서 전달
- 예) 검색, 필터, 페이징 등에서 많이 사용하는 방식 (URL에 노출돼도 상관없는 정보)
2. POST - HTML Form
- content-type : application/x-www-form-urlencoded
- 메시지 바디에 쿼리 파라미터 형식으로 전달 username=hello&age=20
- 예) 회원 가입, 상품 주문, HTML Form 사용 (노출되면 안 되는 정보)
<form action="/request-param-v1" method="post">
username: <input type="text" name="username" />
age: <input type="text" name="age" />
<button type="submit">전송</button>
</form>
3. HTTP message body
- HTTP API에서 주로 사용 JSON, XML, TEXT
- 데이터 형식은 주로 JSON 사용
- POST, PUT, PATCH
HTTP 요청 파라미터 - @RequestParam
스프링이 제공하는 @RequestParam을 이용하면 편안하게 요청 데이터를 사용할 수 있다.
@ResponseBody
@RequestMapping("/request-param-v2")
public String requestParamV2(
@RequestParam("username") String username,
@RequestParam("age") int age
) {
log.info("username={}, age={}", username, age);
return "ok";
}
더 나아가 @RequestParam(key)에서 key와 변수명이 동일한 경우 key를 생략할 수 있다.
@ResponseBody
@RequestMapping("/request-param-v3")
public String requestParamV3(
@RequestParam String username,
@RequestParam int age
) {
log.info("username={}, age={}", username, age);
return "ok";
}
String, int, Integer 같은 단순 타입이면 @RequestParam 생략도 가능하다.
@ResponseBody
@RequestMapping("/request-param-v4")
public String requestParamV4(
String username,
int age
) {
log.info("username={}, age={}", username, age);
return "ok";
}
필수 파라미터 여부
@RequestParam 속성엔 required가 있다. default=true이며, 필수인 값이 없으면 400 에러가 반환된다.
@ResponseBody
@RequestMapping("/request-param-required")
public String requestParaRequired(
@RequestParam(required = true) String username,
@RequestParam(required = false) int age
) {
log.info("username={}, age={}", username, age);
return "ok";
}
만약에 null 값이 올 경우 변수 타입에 신경을 써야 한다.
int 타입은 null을 받을 수 없어서 에러가 발생.
username= 으로 보내면 빈문자로 인식하여 통과될 수도 있다.
@RequestParam은 defaultValue 속성이 존재한다.
@ResponseBody
@RequestMapping("/request-param-default")
public String requestParamDefault(
@RequestParam(required = true, defaultValue = "guest") String username,
@RequestParam(required = false, defaultValue = "-1") int age
) {
log.info("username={}, age={}", username, age);
return "ok";
}
필수 데이터가 없어도 디폴트 값을 지정해서 400 에러가 발생하지 않는다.
Map 타입으로 요청 데이터를 담을 수 있다.
@ResponseBody
@RequestMapping("/request-param-map")
public String requestParamDefault(
@RequestParam Map<String, Object> paramMap
) {
log.info("username={}, age={}", paramMap.get("username"), paramMap.get("age"));
return "ok";
}
만약에 데이터가 배열로 넘어온다면 MultiValueMap을 사용하자.
HTTP 요청 파라미터 - @ModelAttribute
보통 데이터를 받으면 객체를 생성하고 그 객체에 값을 세팅하는데,
스프링은 이 과정을 자동화시켜주는 @ModelAttribute 기능을 제공한다.
@Data
public class HelloData {
private String username;
private int age;
}
@ResponseBody
@RequestMapping("/model-attribute-v1")
public String modelAttributeV1(@ModelAttribute HelloData helloData) {
log.info("username={}, age={}", helloData.getUsername(), helloData.getAge());
log.info("helloData={}", helloData.getUsername());
return "ok";
}
롬복의 @Data를 사용하면
@Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor를 적용해준다.
정상적으로 작동하는지 확인해보자
편하게 객체가 생성되고 값이 세팅되었다.
스프링의 @ModelAttribute 실행 순서
- HelloData 객체 생성
- 요청 파라미터의 이름으로 HelloData 객체 프로퍼티를 찾고, setter 호출해서 값을 바인딩한다.
- 예) 파라미터 이름이 username 이면 setUsername() 을 메서드를 찾아 호출하면서 값을 입력. (요청 데이터와 객체의 프로퍼티 명이 일치해야 한다)
- 만약 타입에 어긋나는 데이터가 들어오면 에러가 발생한다.
@ModelAttribute도 생략이 가능하다.
// @ModelAttribute 생략이 가능
@ResponseBody
@RequestMapping("/model-attribute-v2")
public String modelAttributeV2(HelloData helloData) {
log.info("username={}, age={}", helloData.getUsername(), helloData.getAge());
log.info("helloData={}", helloData.getUsername());
return "ok";
}
스프링은 @RequestParam, @ModelAttribute 생략하면 다음의 규칙을 따른다.
- String, int, Integer 같은 단순 타입이면 @RequestParam을 자동 적용
- 나머지는 @ModelAttribute 를 적용한다. 단, argument resolver로 지정해둔 타입은 제외. (이 내용은 나중에 언급됨)
'교육 및 인강 > 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술' 카테고리의 다른 글
스프링 MVC 기본 기능, HTTP 응답 - 정적 리소스, 뷰 템플릿, HTTP API, 메시지 바디에 직접 입력 (0) | 2021.07.28 |
---|---|
스프링 MVC 기본 기능, HTTP 요청 메시지 - 단순 텍스트, JSON (0) | 2021.07.20 |
스프링 MVC 기본 기능 - 로깅 알아보기, 요청 매핑, API 예시 (0) | 2021.07.19 |
스프링 MVC 이해 - 시작하기, 컨트롤러 통합, 실용적인 방식 (0) | 2021.07.19 |
스프링 MVC 이해 - 전체 구조, 핸들러 매핑과 핸들러 어댑터, 뷰 리졸버 (0) | 2021.07.13 |