본문 바로가기

Development/Spring

[Spring]@RequestParam, @RequestBody, @ModelAttribute의 정의와 차이

종종 HTTP를 이용해 파라미터를 서버로 전송할 때 값이 바인딩이 되지 않는 오류를 경험한 적이 있었다. 이러한 경우 파라미터가 올바른 방법으로 바인딩이 되지 않았기 때문에 발생한 경우가 다수였다.

클라이언트가 HTTP를 이용해 파라미터를 서버로 전송했을 때 스프링에서는 클라이언트로부터 받은 파라미터를 객체로 바인딩하는 역할을 하는 어노테이션에는 @RequestParam, @RequestBody, @ModelAttribute 3가지의 어노테이션이 있다. 이번에는 이 3가지의 어노테이션에 대해서 알아보도록 하자

 

@RequestParam

@RequestParam 어노테이션은 클라이언트가 1개 혹은 여러 개의 HTTP 요청 파라미터를 보냈을 때 보낸 파라미터를 하나씩 받을 때 사용된다. 즉 파라미터를 클라이언트 측에서 몇 개를 보내든지 보낸 파라미터들을 하나씩 파라미터 이름을 이용해 바인딩한다.

 

@RequestParam에 바인딩된 객체에 대응되는 파라미터는 반드시 전송이 되어야 하며, 만약 대응되는 파라미터가 없을 경우에는 400 에러가 발생하며 필수 여부 조건인 required의 false을 통해 필수 조건을 없앨 수 있으며 기본값을 지정해주고 싶으면 defaultValue 옵션을 통해 기본값 설정을 할 수 있다.

또한 HTTP 파라미터 이름이 바인딩된 변수 이름과 같으면 @RequestParam의 name이 생략 가능하며, 바인딩된 변수의 형이 String, int와 같이 단순 타입이면 @RequestParam 역시 생략이 가능하다.

 

@RequestBody

@RequestBody는 클라이언트 측에서 보내는 JSON형태의 HTTP 요청 body를 Java 객체로 변환해 주는 역할을 한다. @RequestBody는 JSON의 body 메시지를 MappingJackson2HttpMessageConverter 통해서 Java 객체로 변환해 준다. 이때 사용되는 클래스는 objectMapper이며 objectMapper에서 제공하는 readValue 메서드를 통해 읽어온 JSON body 메시지를 Java 객체로 변환시켜 준다.

 

@ModelAttribute

@ModelAttribute는 클라이언트가 전송한 폼 데이터를 Java 객체에 자동으로 바인딩을 해주는 역할을 한다. 즉 @ModelAttribute를 사용하면 객체 생성부터 객체에 값을 자동으로 설정해 주기 때문에 파라미터를 하나씩 받아서 Java 객체에 값을 설정해 주는 과정을 한 번에 해결할 수 있는 것이다.

 

@ModelAttribute를 이용해서 HTTP의 body를 이용해서 데이터를 전송할 경우에는 multipart/form-data일 때 전송이 가능하다.

 

@ModelAttribute에서는 int형 변수에 String형 변수를 세팅할 경우 BindException을 발생시키는 것처럼 바인딩 오류를 처리하는 검증 단계가 있다. 그리고 @ModelAttribute는 생략이 가능한데 이럴 경우 역시 생략이 가능한 @RequestParam과 혼란이 발생할 수도 있으니 활용에 있어서 조심해야 된다.