[Retrofit] MultiPart / PartMap 사용하기

Retrofit을 이용하여 개발을 진행하다보면, 

사진을 전송해야하는 경우가 생긴다. 

 

Retrofit을 이용하여 사진을 전송하려면, MultiPart를 사용해야 한다. (사진말고도 파일 전송시 필요하다)


MultiPart ?

클라이언트가 요청을 보낼 때, HTTP 프로토콜 바디 부분에 데이터를 여러 부분으로 나누어 보내는 것이다.

 


설명을 위해, 실제로 진행하였던 프로젝트에서 진행하였던 Request Body를 사용하겠다.

{
	{"image": [이미지 파일]}
}

다음과 같은 형태로 RequestBody를 요구한다.

interface Service {
@Multipart
    @POST("user/update/profile/")
    fun updateProfile(@Part image : MultipartBody.Part) : Call<DefaultRes>
}

 

MulitPart를 사용하기 위해서는  @MultiPart 라는 어노테이션이 반드시 작성되어야 한다.

 

requestBody를 만드는 방법은 다음과 같다.

val requestFile = RequestBody.create("image/*".toMediaTypeOrNull(), uri.toFile())
val body = MultipartBody.Part.createFormData("image", "profile", requestFile)

첫번째 코드에서 Image 리퀘스트 바디를 생성해주고, MulitpartBody.Part 형태로 바꿔주기 위해 formData를 이용하여, 변환하여 body라는 변수에 담아주었습니다.

 

만들어진 body를 이용하여 보내면 끝!

 


+ 추가로 image외에 다른 데이터도 넣어서 전달하려면 PartMap 형태로 만들어서 보내야 한다.

{
	"image": [이미지 파일],
	"feed_id": 1  //이미지가 들어갈 피드의 id
}

위와 달리 feed_id를 추가적으로 요청을 받는다. 이러한 경우에 단순히 Body에 담아서 보내면 오류가 발생한다. MultiPart를 사용하게 되면, Body가 아닌 PartMap에 담아서 데이터를 보내야 한다.

interface Service {
	@MultiPart
	@POST("feed/image/")
	fun uploadImage(@PartMap feed_id : HashMap<String, RequestBody>, @Part image : MultipartBody.Part) : Call<ImageUpload>
}

다음과 같이 HashMap에 담아서 보내줘야 한다.

 

hashMap을 생성하는 코드는 다음과 같다.

val hashMap = HashMap<String, RequestBody>()
hashMap["feed_id"] = userId.toString().toRequestBody()

key - value 형태로 만들어주면 된다.

 

이미지 파일의 requestBody는 위에 코드와 동일하다.