기억 저장소

클라우드 기반 인공지능 개발과 DevOps 실무

프론트엔드/안드로이드 스튜디오

안드로이드 스튜디오 : Multipart 이미지 전송하기 / 여러 데이터 전송하기 /@Part MultipartBody.Part

하늘.98 2022. 3. 16. 16:08

아래의 블로그에서 빌려 왔다.

문제 있을 시 삭제하겠습니다.

아래의 블로그에 정리를 깔끔하게 잘되어있습니다. 아래 블로그를 확인해 보세요 

 

https://velog.io/@dev_thk28/Android-Retrofit2-Multipart%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-Java

 

[Android] Retrofit2 Multipart사용하기 (Java)

Multipart 사용하기

velog.io

단일의 file

한개만 보내면 되는 경우, RequestBody를 사용하면 된다.

 

@Multipart
@POST("api주소")
Call<SomeResponse> request(@Part("key") RequestBody param);

RequestBody는 다음과 같이 만들 수 있다.

String text = "some text";
RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), text);

위 코드는 String을 담기 때문에 MediaType을 "text/plain"으로 지정해줬다.

단일 항목을 모아서 보내기

단일 항목이 많아서 파라미터를 구구절절 쓰기 싫을 때는 Map으로 모아서 보낼 수 있다.

@Multipart
@POST("api주소")
Call<SomeResponse> request(@PartMap Map<String, RequestBody> params);

 

다음과 같이 Map을 만들 수 있다.

RequestBody nameBody = RequestBody.create(MediaType.parse("text/plain"), "철수");
RequestBody ageBody = RequestBody.create(MediaType.parse("text/plain"), "15살");
RequestBody emailBody = RequestBody.create(MediaType.parse("text/plain"), "chulsu@email.com");

HashMap<String, RequestBody> requestMap = new HashMap<>();
requestMap.put("name", nameBody);
requestMap.put("age", ageBody);
requestMap.put("email", emailBody);

put에 들어가는 String은 서버에서 받는 key값? 필드아이디?가 되겠다.

 

 

같은 항목을 여러개 보내기

같은 항목에 대해서 배열로 보내야 할 경우 List를 사용한다.
하지만 RequestBody를 사용하지 않고, MultipartBody.Part를 사용한다.

@Multipart
@POST("api주소")
Call<SomeResponse> request(@Part List<MultipartBody.Part> params);

 

List<MultipartBody.Part>는 다음과 같이 만들 수 있다.

ArrayList<MultipartBody.Part> names = new ArrayList<>();
names.add(Multipart.Part.createFormData("이름", "철수");
names.add(Multipart.Part.createFormData("이름", "제임스");
names.add(Multipart.Part.createFormData("이름", "존");
// 계속 추가...

 

 

여러개의 file

이미지와 텍스트등을 한꺼번에 보내고 싶은경우에

Multipart 를 사용한다.

 

같은 key값으로 여러항목을 보낼 때 처럼 List를 사용한다.

@Multipart
@POST("api주소")
Call<SomeResponse> request(@Part List<MultipartBody.Part> files);

 

file을 담는 List<MultipartBody.Part>는 다음과 같이 만들 수 있다.

// 여러 file들을 담아줄 ArrayList
ArrayList<MultipartBody.Part> files = new ArrayList<>();

// 파일 경로들을 가지고있는 `ArrayList<Uri> filePathList`가 있다고 칩시다...
for (int i = 0; i < filePathList.size(); ++i) {
    // Uri 타입의 파일경로를 가지는 RequestBody 객체 생성
    RequestBody fileBody = RequestBody.create(MediaType.parse("image/jpeg"), filePathList.get(i));
    
    // 사진 파일 이름
    String fileName = "photo" + i + ".jpg";
    // RequestBody로 Multipart.Part 객체 생성
    MultipartBody.part filePart = Multipart.Part.createFormData("photo", fileName, fileBody);
    
    // 추가
    files.add(filePart);
}

 

 

 

 

여러 개의 정보를 보낼 때 예시 

@Multipart
@POST("/dev/v1/memo")
Call<MemoRes> addMemo(@Header("Authorization") String accessToken,
                      @Part MultipartBody.Part photo,
                      @PartMap Map<String, RequestBody> params);
SharedPreferences sp = getSharedPreferences(Utils.PREFERENCES_NAME, MODE_PRIVATE);
                String accessToken = sp.getString("accessToken", "");

                Log.i("MyMemoApp", "1111");
//                MemoReq memoReq = new MemoReq(title, datetime, content);

                RequestBody fileBody = RequestBody.create(photoFile,
                                        MediaType.parse("image/*"));
                MultipartBody.Part part = MultipartBody.Part.createFormData(
                        "photo", photoFile.getName(), fileBody
                );

                Log.i("MyMemoApp", photoFile.getName());


                RequestBody titleBody = RequestBody.create(
                                        MediaType.parse("text/plain"), title);
                RequestBody contentBody = RequestBody.create(
                        MediaType.parse("text/plain"), content);
                RequestBody dateBody = RequestBody.create(
                        MediaType.parse("text/plain"), datetime);

                HashMap<String, RequestBody> requestBodyHashMap =
                        new HashMap<>();
                requestBodyHashMap.put("title", titleBody);
                requestBodyHashMap.put("date", dateBody);
                requestBodyHashMap.put("content", contentBody);

                Call<MemoRes> call = api.addMemo("Bearer "+accessToken,
                        part, requestBodyHashMap);
                Log.i("MyMemoApp", "2222");
                call.enqueue(new Callback<MemoRes>() {
                    @Override
                    public void onResponse(Call<MemoRes> call, Response<MemoRes> response) {
                        dismissProgress();
                        if(response.isSuccessful()){
                            // 200 OK 인 경우
                            // 정상 저장되었으면, 이 액티비티는 끝낸다.
                            setResult(3);
                            finish();
                        }else{
                            Toast.makeText(MemoAdd.this,
                                    "문제 발생",
                                    Toast.LENGTH_SHORT).show();
                            return;
                        }
                    }

                    @Override
                    public void onFailure(Call<MemoRes> call, Throwable t) {
                        dismissProgress();
                        Toast.makeText(MemoAdd.this,
                                "네트워크 문제 발생",
                                Toast.LENGTH_SHORT).show();
                        return;

                    }
                });


            }
        });