해당 포스팅은 인프런스프링 MVC1편 강의를 듣고 적은 강의 노트를 정리하며 기록하기 위한 글입니다.
강의를 시청하며, 프로젝트에 적용할 수 있는 부분들이나 궁금한 기능들을 정리하며 포스팅할 예정입니다.
제 개인적인 의견이 더해져 올바르지 않은 정보가 들어가 있다면, 피드백이나 댓글로 남겨주시면 감사하겠습니다.
자세한 강의 내용은 인프런 스프링 MVC에서 만나보실 수 있습니다.
HTTP 요청데이터조회 - 개요
클라이언트에서 서버로 요청데이터를 전달할 때는 주로 다음 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 HTML Form 전송방식이 든 둘 다형식이 같으므로 구분 없이 조회할 수 있다.
이것을 간단히 요청파라미터(request parameter) 조회라 할 수 있다.
HTTP 요청 파라미터를 조회하는 방법을 알아보자
HTTP 요청 파라미터 - @RequestParam
스프링이 제공하는@RequestParam을 사용하면 요청파라미터를 매우 편리하게 사용할 수 있다.
/**
* @RequestParam 사용
* String, int 등의 단순 타입이면 @RequestParam 도 생략 가능
*/
@ResponseBody
@RequestMapping("/request-param-v3")
public String requestParamV3(
@RequestParam String username,
@RequestParam int age) {
log.info("username={}, age={}", username, age);
return "ok";
}
@RequestParam 애노테이션을 생략하면 스프링 MVC는 내부에서 required=false를 적용한다.
required 옵션은 바로 다음에 설명한다.
@ResponseBody
@RequestMapping("/request-param-default")
public String requestParamDefault(
@RequestParam(required = true, defaultValue = "guest") String username,
@RequestParam(required = false, defaultValue = "-1") Integer age) {
// username "" 빈 문자열도 default 로 걸러줌 "" -> guest
log.info("username={}, age={}", username, age);
return "ok";
}
//username=hello&age=20
//username=hello
//빈문자 && username=
RequestParam.required
파라미터필수여부 기본값이 파라미터필수( true)이다
HTTP 요청파라미터 - @ModelAttribute
보통 데이터를 받으면 객체를 생성하고 그 객체에 값을 세팅하는데,
스프링은 이 과정을 자동화시켜 주는 @ModelAttribute 기능을 제공한다.
@Data
public class HelloData {
private String username;
private int age;
}
여기서 lombok의 @Data를 사용하면, 안에 들어가 있는 @ToString, @EqualsAndHashCode, @Getter, @Setter, @RequiredArgsConstructor 도 같이 사용되는 것이기에 발생하는 문제들이 존재할 수 있다.
1. @ToString : 양방향 연관관계 시 순환 참조
의존성이 1:N 양방향으로 매핑되어 있는 상황을 가정할 수 있다.
이때, ToString을 호출하면 무한 순환 참조가 발생한다.
이러한 문제를 해결하기 위해서는 @ToString(exclude = "coupons")처럼 어노테이션을 사용해서 특정 항목을 제외시키는 방법을 사용할 수 있다.
2. @EqualsAndHashCode
@EqualsAndHashCode는 상당히 고품질의 euqals()와 hashCode() 메서드를 만들어준다.
따라서 잘 사용하면 좋지만, 남발하면 심각한 문제가 생긴다.
특히 문제가 되는 점은 Mutable 객체에 아무런 파라미터 없이 그냥 사용하는 경우이다.
그래서 @Data 보다는 필요에 맞춰서 안에 들어가는 요인들을 잘 사용할 수 있도록 하지만 매우 작은 프로젝트인 이 경우 @Data 어노테이션을 사용해 주었다.
/**
* @ModelAttribute 생략 가능
* String, int 같은 단순 타입 = @RequestParam
* argument resolver 로 지정해둔 타입 외 = @ModelAttribute
*/
@ResponseBody
@RequestMapping("/model-attribute-v2")
public String modelAttributeV2(HelloData helloData){
log.info("username={}, age={}", helloData.getUsername(),helloData.getAge());
return "ok";
}
스프링은 @RequestParam, @ModelAttribute 생략하면 다음의 규칙을 따른다.
- String, int, Integer 같은 단순 타입이면 @RequestParam을 자동 적용
- 나머지는 @ModelAttribute를 적용한다. 단, argument resolver로 지정해 둔 타입은 제외. (이 내용은 나중에 언급됨)
주의해야 할 것
@ResponseBody
@PostMapping("/request-body-json-v5")
public HelloData requestBodyJsonV5(@RequestBody HelloData data) {
log.info("username ={}, age={}", data.getUsername(), data.getAge());
return data;
}
이 경우 HelloData에 @RequestBody를 생략하면 @ModelAttribute 가 적용되어 버린다.
HelloData data -> (default) @ModelAttribute HelloData data
따라서 생략하면 HTTP 메시지 바디가 아니라 요청 파라미터를 처리하게 된다
요청 파라미터 vs HTTP 메시지 바디
요청 파라미터를 조회하는 기능: @RequestParam , @ModelAttribute
HTTP 메시지 바디를 직접 조회하는 기능: @RequestBody
'Back-End > Spring' 카테고리의 다른 글
[MVC-2편] 오류 코드와 메시지 처리 (0) | 2023.04.16 |
---|---|
[MVC-1편] 웹페이지, 타임리프(Thymeleaf) 구성 (0) | 2023.03.22 |
[MVC-1편] given-when-then 패턴이란 (0) | 2023.03.18 |
[MVC-1편] 기본 기능, logging 알아보기 (0) | 2023.03.14 |
[MVC-1편] 동시 요청 - 멀티 쓰레드, 쓰레드 풀 (0) | 2023.03.14 |