[Spring] @RequestParam, @ModelAttribute, @RequestBody 총정리

chaen-ing·2024년 10월 15일
0

Spring 공부

목록 보기
13/13

클라이언트에서 서버로 전달된 요청을 객체로 바인딩하기 위해 사용하는 여러 방법들에 대해서 정리해보겠습니다.

먼저 시작하기에 앞서 클라이언트에서 서버로 요청 데이터를 전달할 때는 주로 다음 3가지 방법을 사용합니다.

  • GET - 쿼리 파라미터
    • /...?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 전송 방식이든 형식이 같아 구분 없이 조회 가능하므로 요청 파라미터 조회 라고 합니다.

→ 즉 크게 2가지로 요청 파라미터 조회 방식, 메세지 바디 방식이 있습니다.

📌 @RequestParam

@RequestParam 애노테이션은 클라이언트가 전송하는 파라미터를 1:1로 받아서 바인딩할때 사용합니다.

@ResponseBody    
@RequestMapping("/request-param")
public String requestParam(
		@RequestParam("username") String memberName,
		@RequestParam("age") int memberAge) {
		
        log.info("username={} age={}", memberName, memberAge);
		return "ok";
	}

위의 예시 코드에서 /request-param?username=kim&age=20이라는 요청이 들어오면
→ getParameter("username")을 통해 memberName에 값이 바인딩됩니다

  • HTTP 파라미터 이름과 변수 이름이 같으면 (name=”xx”) 생략 가능
    ex) @RequestParam String username
  • String , int , Integer 등의 단순 타입이면 @RequestParam도 생략 가능
    ex) String username
  • 그러나 스프링 3.2부터 파라미터 이름 인식 문제가 발생하는 경우가 있으니 생략하지 않는 것을 추천합니다..(명시적으로도 생략하지 않는 것을 추천)

추가적으로 파라미터 필수여부(required), 기본값 적용(defaultValue)도 적용 가능합니다.

📌 @ModelAttribute

@ModelAttribute는 요청파라미터를 받아서 필요한 객체를 만들고 그 객체에 값을 넣어주는 과정 자동화시키는 애노테이션입니다.

@ResponseBody
@RequestMapping("/model-attribute")
public String modelAttribute(@ModelAttribute HelloData helloData) {
	log.info("username = {} age = {}", helloData.getUsername(), helloData.getAge());
	return "ok";
}

위의 코드 예시를 통해 과정을 살펴보겠습니다.

스프링 MVC는 @ModelAttribute가 있으면 생성자를 통해 HelloData를 객체 생성
→ 요청 파라미터의 이름으로 HelloData 객체의 property를 찾음
(객체에 getxxx, setxxx 메서드가 있으면 xxx라는 프로퍼티를 갖고있는 것)
setter 호출해서 파라미터의 값을 바인딩

즉 해당 애노테이션을 사용하려면 생성자와 Setter함수가 필수적으로 있어야합니다

@ModelAttribute에서는 타입이 잘못들어가면 BindException이 발생합니다.

또한 @RequestParam과 동일하게 애노테이션 생략이 가능합니다.

  • Stirng, int, Integer 등 단순 타입 : @RequestParam
  • 나머지 : @ModelAttribute

📌 @RequestBody

@RequestBody는 Http 메시지 바디에 내용을 담아서 요청이 오면 이를 변환할 때 사용하는 애노테이션입니다.
메시지 바디로 들어온 메시지는 @RequestParam이나 @ModelAttribute로 당연히 읽을 수 없습니다.

@ResponseBody
@PostMapping("/request-body-string")
public String requestBodyString(@RequestBody String messageBody) throws IOException {
	log.info("messageBody = {}", messageBody);

	return "ok";
}
@ResponseBody
@PostMapping("/request-body-json")
public HelloData requestBodyJson(@RequestBody HelloData data) {
	log.info("username={}, age={}", data.getUsername(), data.getAge());
	return data;
}

String, JSON 타입 모두 @RequestBody 애노테이션을 통해 받을 수 있습니다.
받은 메시지 바디는 내부의 HttpMessageConverte가 알아서 String 또는 객체 타입으로 변환해줍니다.

이때 @ModelAttribute처럼 setter를 사용하는 것이 아니라 생성자를 통해 객체를 생성합니다.

주로 JSON -> 객체 타입 변환에 많이 사용됩니다.

응답의 경우에도 @ResponseBody를 사용하면 컨버터가 자동으로 변환해줍니다.

(컨버터에 관한 내용은 추후에 자세히 써보겠습니다..!)

✔️ 정리

@RequestParam@ModelAttribute@RequestBody
HTTP 요청 종류요청 파라미터 조회요청 파라미터 조회메시지 바디
특징- 요청 파라미터의 1:1 바인딩
- 파라미터의 필수값 여부, 기본값 지정 가능
- 생략 가능
- 요청 파라미터를 받고 객체 자동 생성 및 바인딩
- 생략 가능
- http 메시지 바디 내용 자동 변환
사용 예시- 검색이나 필터링
- GET
- 검증이 필요한 상황
- GET
- HTTP API에서 주로 사용
- JSON을 전송해야하는 상황
- POST
profile
💻 개발 공부 기록장

0개의 댓글

관련 채용 정보