Spring에서 FormData 를 파싱(Parsing) 하지 못하는 경우

Denia·2022년 5월 4일
1

TroubleShooting

목록 보기
4/25

1. 문제상황

  1. FE(React)에서 Axios 를 사용해서 FormData를 BE(Spring)한테 Post 요청을 하지만 Spring에서 해당 FormData를 파싱(Parsing) 하지 못하는 이슈
  2. BE에서는 이미 PostMan으로 해당 API 테스트를 완료한 상황

※에러메세지에서 List < MultipartFile > Files 를 파싱하지 못한다고 자꾸 에러가 떠서 MultipartFile 관련된 문제인줄 알았으나 FE에서 보내주는 데이터와 Spring에서 처리하는 데이터가 bindig이 안되는 이슈인거 같다. 만약 binding issue가 발생한다면 지금 나타나는 문제와 비슷하다고 본다. 오타문제가 아니라면..?

1.1 FE

1.1.1 formdata 주는 형식

formdata.append("files",prop.files) // files 는 배열
formdata.append("title",prop.title) 
formdata.append("contents",prop.contents) 

1.1.2 Request Header

1.2 BE

1.2.1 Log에 뜨는 에러 메시지

Spring에서 뜨는 에러 메세지는 다음과 같다!

에러 메세지에서 중요한 내용을 Text로 뽑아보면 아래와 같다.

Feild error in object 'boardRequestDto' on field 'files' : rejected value [[object File]];
codes [typeMismatch.boardRequestDto.files,typeMismatch.java.util.List,typeMismatch]; ...(1)

...

default message [Failed to convert property value of type 'java.lang.String'
to required type 'java.util.List' for property 'files'; ...(2)

nested exception is java.lang.IllegalStateException
: Cannot convert value of type 'java.lang.String' 
to required type 'org.springframework.web.multipart.MultipartFile' 
for property 'files[0] : no match editors or conversion strategy found']  ...(3)

해석을 해보면 다음과 같다.

  1. TypeMismatch가 발생해서 [[object File]] 값이 거절되었으며
  2. property files 에 관해서 String type 값을 필요한 List type 으로 변환하는데 실패했다고 한다.
  3. 2번과 비슷한 내용으로 files[0]에 관해서 String type을 MultipartFile type으로 바꿀수 없다고 한다. (MultipartFile은 FormData에서 파일 관련 클래스)

2. 문제해결

해당 문제로 몇시간을 고생을 하다가

  1. FE에서 Axios를 Ajax로 테스트 해보고, Content/type을 넣었다가 뺏다가 , key-value를 다르게도 줘보고 등등 했고

  2. BE에서도 List 대신에 그냥 클래스로 받아봤다고 RequestParam 대신에 RequestPart 도 써보고 내부클래스 대신에 그냥 Dto로도 받아보고 등등 했음

2.1 문제해결 실마리

아래의 블로그 글을 보고 ( 이부분을 특히 ※여러 개의 파일을 한 번에 업로드할 경우 동일한 Key값으로 여러번 추가 )

( ※이미지 출처 : https://gaemi606.tistory.com/entry/Spring-Boot-multipartform-data-%ED%8C%8C%EC%9D%BC-%EC%97%85%EB%A1%9C%EB%93%9C-React-Axios-REST-API )

FE에서 주는 FormData의 Value 값을 배열로 주는 것이 아니라 단일 객체들로 주는것으로 테스트 해봐야겠다고 생각했다.

2.1.1 FE에서 데이터 주는 방식을 배열을 주는 방식에서 단일 객체 여러개를 보내주는 방식으로 변경

FE에서 formdata로 files 라는 이름의 key 로 배열을 쪼개서 따로따로 보내주기로 함

// formdata.append("files",prop.files) // files 는 배열  ... (1)
// ================================================================
formdata.append("files",prop.files[0]) // files 는 배열  ... (2)
formdata.append("files",prop.files[1]) // files 는 배열
formdata.append("files",prop.files[2]) // files 는 배열
formdata.append("title",prop.title) 
formdata.append("contents",prop.contents) 

다음과 같이 처리를 해서 보내줬더니 (1번 대신에 2번 방식을 사용함)
Spring 에서 제대로 파싱(Parsing)이 가능해졌다.

files를 여러개로 쪼개서 보내더라도 Spring에서는 List < MultipartFile > files 형태로 받아서 처리가 가능하다.

3. 후기

문제는 상당히 간단했는데 배열로 보내주는 것 때문에 문제가 생겼을 것이라고는 예상을 전혀 하지못해서 시간을 많이 사용한 것 같다.

profile
HW -> FW -> Web

2개의 댓글

comment-user-thumbnail
2022년 7월 29일

저도 여기서 헤매고 있었는데 ㅋㅋㅋ 너무 감사합니다~

1개의 답글