본문 바로가기

COTATO.KR 프로젝트

Multipart/form-data convert(역직렬화) 오류 해결

프로젝트를 진행하다 file과 속성 값이 같이 있는 DTO를 swagger에서 백엔드 넘기는 상황에 직면했다.

 

이 때 중첩된 DTO를 사용할 때 convert 오류가 발생한다.

record request(
String placeName,
@NotNull LocalDate sessionDate,
@Valid @NotNull AttendanceDeadLineDto attendanceDeadLine)
cannot convert value of type 'java.lang.string' to required type dto

 

헤당 문제는 중첩된 DTO를 사용할 때 swagger에서는 form-data 상태에서 중첩된 DTO를 객체가 아닌 String으로 인식한다.

 

따라서 AttendanceDeadLineDto를 객체를 받지 않고 String 배열로 인식해 서버로 보내준다.

 

그리고 당연하게도 String -> AttendanceDeadLineDto 로 역직렬화될 수 없어 발생한다.

 

해당 문제를 해결할 수 있는 방법은 다음과 같다.

 

  1. Multipart 파일은 따로 DTO를 구성하고 다른 프로퍼티는 Json으로 선택해서 따로따로 보낼 수 있는 것
  2. 중첩된 하위 객체를 없애는 쪽으로 request DTO 구조를 바꾸는 것
  3. API를 분리해서 파일은 multipart-form으로, 중첩된 DTO는 json으로 따로 받는다.

하지만 postman에서는 1번 방식이 가능하지만 swagger를 사용하는 상황에서는 1번 방법을 사용할 수 없다.
따라서 2,3번 중에 cost가 적은 2번을 선택했다.

 

record request(
        @Schema(example = "17:00:00")
        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "HH:mm:ss")
        LocalTime startTime,

        @Schema(example = "17:00:00")
        @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "HH:mm:ss")
        LocalTime endTime
)

 

AttendanceDeadLineDto -> startTime, endTime으로 중첩을 풀어 해결했다.

 

또한 LocalTime은 swagger 상에서 기본 객체가 다음과 같다.

"time": {
    "hour": 0,
    "minute": 0,
    "nano": 0,
    "second": 0
  }

 

따라서 백엔드에서는 HH:mm:ss로 읽지 못해 또 convert 오류가 발생했다.

 

이 때 @Schema를 통해 양식을 정해줘 프론트엔드 입장에서 양식을 쉽게 알수 있게 했다.