본문 바로가기
Spring

[Spring] @ModelAttribute와 @RequestBody의 데이터 바인딩

by Nhahan 2024. 4. 5.

1. @ModelAttribute를 사용한 경우

@Getter
@Setter // @Setter가 빠진다면?
public class FileUploadDto {
    private String description;
    private MultipartFile file;
}

@Controller
public class FileUploadController {

    @PostMapping
    public void uploadFile(@ModelAttribute FileUploadDto fileUploadDto) {
        MultipartFile file = fileUploadDto.getFile();
        String description = fileUploadDto.getDescription();
    }
}

위 코드에서 @ModelAttribute는 HTTP 요청의 파라미터를 객체에 매핑할 때 Setter 메서드를 내부적으로 사용한다.
따라서 FileUploadDto 클래스에서 @Setter가 없을 경우, file이나 description 같은 필드에 값이 제대로 바인딩되지 않는다. 결국 null 값이 필드에 들어가게 되고, 이후 이를 사용하는 과정에서 NullPointerException 등의 에러가 발생할 가능성이 크다.

 

동작 과정

  1. @ModelAttribute는 HTTP 요청의 form-data나 query parameter 값을 읽는다.
  2. 읽은 데이터를 객체의 필드에 매핑할 때, 각 필드에 해당하는 Setter 메서드를 호출한다.
  3. 만약 Setter 메서드가 없다면, 매핑 과정에서 실패하여 필드 값이 null로 남는다.

 


 

2. @RequestBody를 사용한 경우

@Getter
public class UserDataDto {
    private String name;
}

@RestController
public class UserController {

    @PostMapping("/users")
    public String registerUser(@RequestBody UserDataDto userDataDto) {
        return "User " + userDataDto.getUsername() + " registered successfully!";
    }
}

@RequestBody를 사용하는 경우에는 @Setter가 없어도 정상적으로 데이터가 매핑된다.
이유는 @RequestBody가 JSON 등의 데이터를 Jackson 같은 라이브러리의 ObjectMapper를 통해 객체로 변환하기 때문이다. Jackson은 객체 생성 시 Reflection을 사용하여 필드에 직접 값을 할당하므로 Setter 메서드가 없어도 데이터 매핑이 가능하다.

 

동작 과정

  1. HTTP 요청의 Body를 JSON 등의 형태로 받는다.
  2. Jackson(ObjectMapper)이 이 데이터를 파싱하여 DTO 클래스의 필드에 직접 값을 할당한다.
  3. Reflection을 사용하므로 Setter 메서드가 없어도 정상적으로 동작한다.

 

 

 

 

댓글