스프링에서 클라이언트로 받은 요청을 객체로 바인딩하기 위해 사용하는 방법을 알아보자.
@RequestParam
- @RequestParam은 1개의 HTTP 요청 파라미터를 받기 위해서 사용한다.
- @RequestParam은 필수 여부가 true이기 때문에 반드시 해당 파라미터가 전송되어야 한다.
- 파라미터가 전송되지 않으면 400 에러가 발생한다.
- 반드시 필요한 값이 아니라면 required를 false로 설정해 주면 되고, defaultValue 옵션을 사용하면 기본값 역시 지정할 수 있다.
// searchKeyWord는 required가 false이기 때문에 없을 수도 있으므로, 없다면 기본값이 할당된다.
@GetMapping("/list")
public ResponseEntity<List<Board>> requestParam(
@RequestParam(required = false, defaultValue = "taesoo") String searchKeyWord) {
return ResponseEntity.ok(boardService.getBoardList(searchKeyWord));
}
@RequestBody
- @RequestBody는 클라이언트가 전송하는 Json(application/json) 형태의 HTTP Body를 Java 객체로 변환시켜 주는 역할을 한다.
- @RequestBody로 받는 데이터는 Spring에서 관리하는 MessageConverter들 중 하나인 MappingJackson2 HttpMessageConverter를 통해 Java 객체로 변환되는데, 이는 ObjectMapper라는 클래스를 사용한다.
- 데이터 형식이 Json이 아닐 수도 있다.
ObjectMapper의 동작 과정
ObjectMapper는 Json 메시지를 자바 객체로 변환하는 과정에서 객체의 기본 생성자를 통해 객체를 생성하고, 내부적으로 Reflection을 사용한다. 그래서 반드시 @Setter가 필요한 것은 아닌데, @Getter나 @Setter 혹은 @JsonInclude 등 필드에 있는 변수들의 이름을 찾기 위한 메서드들을 필요로 한다. 그러므로 기본생성자 + @Getter로 클래스를 구현해 주면 @Setter가 없어도 값이 바인딩된다.
// @RequestBody는 MessageConverter를 통해 Json 형태의 HTTP Body를 Java 객체로 변환시킨다.
@PostMapping("/requestBody")
public ResponseEntity<Board> requestBody(@RequestBody Board board) {
return ResponseEntity.ok(board);
}
@ModelAttribute
- 클라이언트가 전송하는 폼(form) 형태의 HTTP Body와 요청 파라미터들을 생성자나 Setter로 바인딩하기 위해 사용된다.
- @ModelAttribute에는 매핑시키는 파라미터의 타입이 객체의 타입과 일치하는지 등을 포함한 다양한 검증(Validiation) 작업이 추가적으로 진행되는데, 예를 들어 int형 index 변수에 "1번"이라는 String형을 넣으려고 한다면, BindException이 발생하게 된다.
- @ModelAttribute을 사용해서 특정 Parameter 값 만을 가져올 수도 있다.
ModelAttribute의 동작 과정
ModelAttribute는 먼저 Reflection을 사용해 필드를 인자로 받는 생성자가 있는지 검사한다. 만약 있다면 해당 생성자를 이용해 값을 세팅하고 없다면 Setter로 값을 세팅한다. 예를 들어 모든 필드를 인자로 받는 생성자가 있다면 해당 생성자로 값을 주입한다. 만약 없다면 일부 필드를 인자로 받는 생성자를 찾아 사용하고, 없으면 기본 생성자를 사용해 객체를 생성한다. 그리고 생성자로 주입하지 못한 남은 변수들은 Setter를 이용해 값을 할당한다.
// @ModelAttribute는 폼(form) 형태의 HTTP Body와 요청 파라미터들을 객체에 바인딩시킨다.
@PostMapping("/modelAttribute")
public ResponseEntity<Board> modelAttribute(@ModelAttribute Board board) {
return ResponseEntity.ok(board);
}
요약
- RequetParam
- 1개의 HTTP 파라미터를 얻기 위해 사용되며 기본값을 지정할 수 있음
- 필수 여부가 true이기 때문에 반드시 필요한 경우가 아니라면 required=false 설정이 필요함
- RequestBody
- Json(application/json) 형태의 HTTP Body 데이터를 MessageConverter를 통해 Java 객체로 변환시킴
- 기본 생성자로 객체를 만들고, Getter나 Setter 등의 메서드로 필드를 찾아 Reflection으로 값을 설정함
- ModelAttribute
- 폼 형태(form)의 HTTP Body와 요청 파라미터들을 객체에 바인딩시킴
- 기본적으로 생성자로 값이 설정되고, 생성자로 설정되지 않은 필드는 Setter로 설정됨
@RequestParam, @RequestBody, @ModelAttribute는 모두 어노테이션이다. 어노테이션은 기능을 갖고 있지는 않으므로 실제로는 해당 어노테이션이 있음을 인지하고, 어노테이션에 맞는 처리기가 동작하는 방식으로 동작한다. Spring에서 해당 처리기는 ArgumentResolver 인터페이스이며, 각각의 어노테이션일 때 사용되는 구현체들이 존재한다.
'Spring' 카테고리의 다른 글
@Configuration안에서 @Bean을 사용해야하는 이유 (0) | 2023.05.05 |
---|---|
@Bean,@Configuration,@Component 차이점 (0) | 2023.05.05 |
@Controller와 @RestController 차이점 (0) | 2023.05.04 |
Servlet, Spring MVC 정리 (0) | 2023.01.30 |
Spring Security + JWT 회원가입, 로그인 기능 구현 (7) | 2023.01.17 |