728x90

 

개요

프로젝트를 진행하던 중 S3에 파일을 업로드하는 로직에서 문제가 발생했습니다.

 

S3로 파일 업로드를 할 때 bodyform-data로 데이터를 보내야 합니다. 그러나 파일 업로드 API 요청을 할 때 다른 DTO 정보도 함께 보내야 했기 때문에 @ModelAttribute 어노테이션을 사용하여 데이터를 전달했습니다.

 

그러나 아래의 트러블슈팅 포스팅에서 알게 된 바와 같이 @ModelAttribute복잡한 타입의 데이터에 대해 자동 변환을 지원하지 않는다는 점을 발견했습니다.

 

그렇다면 @ModelAttribute가 자동 변환할 수 있는 타입에는 어떤 것들이 있는지 살펴보겠습니다.

 

 

[트러블 슈팅] @ModelAttribute의 자동 변환 에러 해결

문제 상황 문제 코드 @PostMapping public GlobalResponse uploadMultimedia( @RequestParam("file") MultipartFile file, @ModelAttribute MultimediaDto.Request requestDto ){ MultimediaDto.Response responseDto = multimediaService.uploadMultimedia(file,req

pixx.tistory.com

 

@ModelAttribute가 자동 변환 할 수 있는 타입

기본 데이터 타입

  • String: 문자열
  • int, Integer: 정수형
  • long, Long: 긴 정수형
  • double, Double: 실수형
  • boolean, Boolean: 논리형

Wrapper 클래스

  • Integer
  • Long
  • Double
  • Boolean

Date 및 시간 관련 타입

  • java.util.Date
  • java.sql.Date

컬렉션 타입

  • List
  • Set
  • Map

@ModelAttribute가 자동 변환 할 수 없는 타입

UUID

  • Spring은 기본적으로 String 값 자동으로 매핑하려고 시도합니다.
  • 하지만 UUID는 단순 문자열이 아니기 때문에, 추가적인 변환 로직 없이는 @ModelAttribute로 바인딩할 때 오류가 발생할 수 있습니다.

LocalDate & LocalDataTime

  • 날짜/시간 정보를 단순 문자열로 받을 수 있지만, LocalDateLocalDateTime 같은 타입은 특정 형식(yyyy-MM-dd, yyyy-MM-dd'T'HH:mm:ss)으로 변환해야 합니다.
  • Spring에서는 기본적으로 자동 변환되지 않기 때문에, 수동으로 변환을 추가해야 합니다.

Enum

  • Enum 타입도 문자열과 다르게 처리되기 때문에 @ModelAttribute에서 변환이 자동으로 이루어지지 않을 수 있습니다.
  • 예를 들어, "ADMIN"이라는 문자열을 UserRole.ADMIN으로 변환하려면 Spring이 내부적으로 타입 변환 로직을 제공하거나 커스텀 변환기를 추가해야 합니다.

복잡한 객체

  • @ModelAttribute는 기본적으로 간단한 필드들을 문자열 형태로 받아서 바인딩하는 데 적합합니다.
  • 그러나 다중 필드를 가지는 복잡한 객체(예: 객체 내에 객체가 포함된 경우) 또는 List, Map과 같은 컬렉션 타입을 처리하려면 별도의 변환 설정이 필요합니다.

Optional

  • Java의 Optional 타입은 Spring이 자동으로 처리하지 못합니다.
  • Optional은 실제 값을 감싸는 컨테이너이기 때문에, 단순히 String이나 다른 기본 데이터 타입으로 변환되지 않습니다.

BigDecimal

  • BigDecimal은 숫자를 매우 정확하게 표현하는 타입인데, 이 역시 String에서 직접 변환할 수 없기 때문에 별도의 변환기가 필요합니다.

커스텀 변환기 예시

@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(LocalDate.class, new PropertyEditorSupport() {
        @Override
        public void setAsText(String text) {
            setValue(LocalDate.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        }
    });
}

 

이렇게 하면 @ModelAttribute로 넘어오는 데이터에 대해 필요한 변환을 추가할 수 있습니다.