spring boot <-> flutter 이미지 전송 시 문제 해결

joydevme·2022년 1월 15일
0
post-thumbnail

요즈음 공부하고 있는데 혼자서 매우 고군부투 했던,,
내용들을 나중에 혹시라도 문제가 생겼을 때 볼 수 있도록 기록을 남기기로 했다.

학부생 + 취준생 시절에는 자바를 배웠지만 직장 생활 이후 자바가 매우 많이 발전하여 변경되었다. 자바 공부도 할 겸 새로운 걸 접하고 싶어서 이번 프로젝트는 코틀린 + 스프링 부트로 진행하게 되었다.(공부하려고 했던건 자바인데,, 왜 코틀린으로 하기 시작했을까) 경력에 비해 내가 아는 것이 많지 않다는 것을 통감하는 중이다.(매우 반성함)

기존 laravel을 할 때는 파일을 받는 방법에 대해서 고민할 필요가 없었다. Request 객체를 파라미터로 넘겨주면 그 안에 있는 파일을 가져와서 쓸 수 있었다.

다음은 spring boot <-> flutter 간의 이미지 전송을 기능을 만들면서 내가 어려움에 부딧혓던 내용들을 정리해봤다.

case 1.

flutter에서 서버 통신 시 http와 dio를 사용할 수 있는데 보통 편의성을 위해 dio를 추가적으로 사용한다고 한다. dio가 없어도 http만으로 충분히 사용 가능하다.
내가 dio를 이용한 것은 dio에서 제공하는 기능 때문인데 response로 온 json 데이터를 바로 map 객체로 변환 가능하다.

http의 경우에는 response를 json decode 후 Map 객체에 할당 가능하고 dio를 쓰는 것에 비해 한 번의 처리가 더 필요하다.

http 사용 시

var response = await http.get("url");
var items = json.decode.(response.body);
var userObject = UserObject.fromJson(item)

dio 사용 시

var response = await.dio.get("url")
var userObject = UserObject.fromJson(reseponse.body)

편의성 때문에 dio를 선택하다보니 문제가 생겼다.
보통 나는 테스트를 할 때 시뮬레이터를 돌리기 보다는 chrome으로 돌리는데 dio의 경우 웹은 지원하지 않는다,, 여러 블로그를 뒤져가면서 찾았지만 다른 문제인 것으로 생각해서 진행을 했기 때문에 이게 문제가 될거라고 생각하지 않았다.

기억해두기!!

앱 프로젝트만 하는 경우 -> dio, http 전부 사용 가능
웹 프로제트만 하는 경우, 앱, 웹 둘 다 지원하려고 하는 경우 -> dio, http 전부 사용 가능하지만 파일 업로드 시 dio는 웹에는 지원을 하지 않는다.

case 1 해결 완료 (+2일)

case 2

flutter 공식홈에서는 formData에 file을 포함하여 보내는 식으로 되어있으나, 실행시 spring boot에서 파일을 제대로 받을 수 없었다. 다음과 같은 형태로 보낼 시에는 file을 받을 수 있다.

case 2 해결 완료 (+2일)

case 3

스프링 부트의 경우 request시 객체 컨버젼을 지원한다.
어노테이션을 이용해 미리 만들어둔 request dto에 컨버젼을 시켜주는데 각 어노테이션 마다 쓰임새가 다른데 원래 어노테이션을 쓰지않았고 계속 비슷한 api만을 생성하다보니 무엇이 문제인지 찾기가 어려웠다.

각 어노테이션 별 기능을 확인하고 쓸 것!

@RequestBody의 경우 json이나 xml을 요청 시 사용하고 파일 전송 시 multipart/form-data로 전송 되기 때문에 json을 dto로 컨버젼 할 수 없다.

@ModelAttribute는 JSP 사용 시 form 의 인자들과 테스트 코드의 account를 맵핑 시켜준다. ()안의 객체의 이름으로 뷰단까지 전달되며 JSP 내에서 사용 가능하다.

multipart/form-data로 전송 시에 객체에 매핑을 원한다면 어노태이션을 붙이지 않거나 @RequestParam,@RequestPart를 사용할 수 있다. RequestParam과 RequestPart를 쓰는 경우 객체로 컨버젼이 되지 않기 때문에 객체인 경우에는 어노테이션이 없이 아닌 경우에는 어노테이션을 추가하여 주었다.

case 3 해결 완료 (+2일)

case 4

모든 문제들을 다 해결 완료 했다고 생각했으나 아직 객체에 컨버젼이 되지 않는 문제가 있었다.
몇일동안 코드를 갈아엎으면서 다시 했는데도 안되어서 뭐가 문제인지 엄청 고민했는데,,,
의외로 간단한 문제였다. 스스로 만든 함정 문제,,

스프링을 접하면서 버릇처럼 dto를 만들 경우 스네이크 케이스와 카멜 케이스 문제로 인해 버릇처럼 @JsonProperty을 붙였다. multipart/form-data로 받기 때문에 json이 아니여서 컨버젼이 되지 않았고 객체의 값들이 전부 null로 넘어왔다.

이후 @JsonProperty를 제거하여 객체에 바인딩이 제대로 일어났다. 추가적으로 이 문제를 해결하기 위해서는 file을 제외한 파라미터들에 따로 application/json으로 타입을 지정하면 된다.

case 4 해결 완료 (+2일)


요약

  • dio 패키지를 사용하는 경우, 웹에서는 파일 업로드를 할 수 없다.
  • dio FormData를 이용해서 보내는 경우 파일을 받을 수 없다면 FormData 객체의 files에 추가를 해보자!
  • api에서 request 데이터를 dto 객체로 컨버젼 시에는 어노테이션을 주의하자!
  • 어디에서든,, 어노테이션을 주의하자! @JsonProperty는 json key값을 지정하는 것이다,,

별로 어렵지 않은 문제들로 약 8일이 걸렸다.(사실은 중간에 질려서 잠깐 쉬는 바람에 더 걸렸음,, 반성하는 부분) 자바와 스프링을 꾸준히 하거나 나처럼 야매가 아닌 정식으로 코스를 밟는 경우에는 위와 같은 문제에 부딧히지 않을 것 같다 ㅠㅠ 나란 존재,, 화이팅,,,
profile
백엔드 ~> 프론트엔드

0개의 댓글