0

I am trying to upload an array of files, an authorization header, and a java object.

The issue is the way the backend is setup, I do not want to name the @Part annotation for my DocumentUpdateObject. Is there a way to allow for @Part(null), or to convert my custom object (DocumentUpdateObject) into a MultipartBody.Part? I'll post some examples to explain better.

The array of files is technically optional, so this statement below works perfectly.

@PUT("document/")
Call<ResponseBody> updateDocument(
        @Header("Authorization") String token,
        @Body DocumentUpdateObject object);

What I would like to have functional is something similar to this:

@Multipart
@PUT("document/")
Call<ResponseBody> updateDocumentDocs(
        @Header("Authorization") String token,
        @Part DocumentUpdateObject object,
        @Part ArrayList<MultipartBody.Part> files);

In regards to the second parameter, if I do not give @Part a name, @Part("object"), then it fails. If I give @Part a name then the backend is unable to read it properly. I wants to read it similar to @Body above.

Is there code for converting an object to a MultipartBody.Part (if that would solve it)? I've seen a couple solutions but they seem to only work for simple single String requests. My DocumentUpdateObject has 5 variable parameters including another object with 5 more variable parameters. I have considered MultipartBody.Builder, but it doesn't appear to handle nested objects.

Edit: This is all read expecting a JSON format

Edit 2: Basically I was able to get part of the object to send by breaking it apart, but the final object inside of it I have been unable to process properly.

//These request bodies send properly
RequestBody defncynbrBody =
            RequestBody.create(deficiencyNbr, MediaType.parse("application/json"));
RequestBody assetBody =
            RequestBody.create(assetnbr, MediaType.parse("application/json"));
RequestBody subassetBody =
            RequestBody.create(subassetnbr, MediaType.parse("application/json"));

//This object down here still is unable to be recieved properly
Gson gson = new Gson();
String json = gson.toJson(add);
RequestBody addBody =
            RequestBody.create(json, MediaType.parse("application/json"));

Edit 3

This does not properly work

   Content-Disposition: form-data; name="defncy"
    2019-09-25 10:20:24.123 D/OkHttp: Content-Transfer-Encoding: binary
    2019-09-25 10:20:24.123 D/OkHttp: Content-Type: application/json; charset=utf-8
    2019-09-25 10:20:24.123 D/OkHttp: {"defncytyp":"LOW","descr":"details are here this",
    "duedate":"2019-09-23","maintlogcattyp":"INTR","title":"Newest one"}

Yet this one works great.

2019-09-25 10:31:58.404 D/OkHttp: Content-Type: application/json; charset=UTF-8
2019-09-25 10:31:58.405 D/OkHttp: {"defncy":{"defncytyp":"LOW","descr":"details are here this",
"duedate":"2019-09-23","maintlogcattyp":"INTR","title":"Newest on"},"assetnbr":4,"defncynbr":18,"subassetnbr":0,"usrs_assigned":0}
C. Skjerdal
  • 2,750
  • 3
  • 25
  • 50

1 Answers1

0

Your backend will be accepting Parts with a single key, mostly in back-end side, we treat multiple part files as Part[].
So, try to build your part objects this way:

@NonNull
private List<MultipartBody.Part> getParts(@NonNull String key, @NonNull List<File> files) {
    final MultipartBody.Builder builder = new MultipartBody.Builder();
    for (File file : files) {
        final RequestBody body = RequestBody.create(MediaType.parse("image/*"), file);
        builder.addFormDataPart(key, file.getName(), body);
    }
    return builder.build().parts();
}

then call your updateDocumentDocs method

@Multipart
@PUT("document/")
Call<ResponseBody> updateDocumentDocs(
    @Header("Authorization") String token,
    @Part DocumentUpdateObject object,
    @Part List<MultipartBody.Part> files);
Harsh Jatinder
  • 833
  • 9
  • 15
  • Sorry I think I should have clarified better, or I am misunderstanding your answer. My "@Part ArrayList file" worked just fine. The issue was passing the DocumentUpdateObject which contains strings, ints, and an object containing more Strings/Ints. Thank you for taking the time to reply though. I'll update my question for clarity – C. Skjerdal Sep 24 '19 at 19:34
  • Fixed up my question a bit, I had a few grammatical errors as well. – C. Skjerdal Sep 24 '19 at 19:37