1

How can i upload image file along with my json.

My request JSON looks in the below format.

{
    "Request": {
        "first_name": "Josmy",
        "last_name": "J",
        "profile_image_attributes": {
            "image":"file"
        }
    }
}

In my gson class i am inputting values some what like this

public class Request implements Serializable {
    @SerializedName("first_name")
    private String firstName;
    @SerializedName("last_name")
    private String lastName;
    @SerializedName("profile_image_attributes")
    private MultipartBody.Part profileImageAttributes;
}

@Headers("Content-Type:application/json")
@POST(PSDApiconstants.REGISTRATION)
Observable<PSDSignUpResponseBean> registration(@Body PSDRegistrationRequestBean requestBean);

is there any way without changing the request to

  {
      "imag": "File",
      "first_name": "Josmy",
      "last_name": "J",
    }

EDIT

Currently I think retrofit 2.0.1 dosen't support image upload in this pattern. so i use Asynchttp to solve this problem. But may be retrofit 2 will include this in their latest release by the end of july

Nivedh
  • 971
  • 1
  • 8
  • 19
  • 1) What do you call "multipart file"? 2) There's no such thing as multipart inside JSON. 3) If you want to put an image inside JSON you'll want to encode it in Base64. 4) If you want to put more of these under one key such as `image` above you will have to separate these Base64 encoded images via a separator of your choice e.g. `***`. 5) In any case the server dictates the format so your question does not make much sense. Send what the server expects. – Eugen Pechanec Jun 13 '16 at 10:01
  • @EugenPechanec I need to pass as multipart image, not as base 64. Is it possible? – Nivedh Jun 14 '16 at 11:46
  • 1
    Again, what's "multipart image"? There's no such thing as "multipart JSON", "multipart file", "multipart image", "multipart whatever". **HTTP POST body can be multipart** in which case you'd send JSON SEPARATOR IMAGE1 SEPARATOR IMAGE2 SEPARATOR IMAGEn etc. HTTP POST body can be JSON only and images can be Base64 encoded within that JSON. **There's nothing in between.** You as a client of the API have no say in this. Ask your API developer what is the format API expects. Is it really multipart? Good, what is the format of JSON request and what is the multipart separator (boundary). – Eugen Pechanec Jun 14 '16 at 11:54
  • This may interest you http://stackoverflow.com/questions/16958448/what-is-http-multipart-request – Eugen Pechanec Jun 14 '16 at 11:56

2 Answers2

1

In retrofit 2.0 you can upload image using MultipartBody.Part.

Declare your service

@Multipart
@POST("/api/imageupload")
Observable<Response> uploadImage(@Part MultipartBody.Part imageFile);

Create your retrofit client object and call your api.

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(YOUR_API_URL)
        .addConverterFactory(GsonConverterFactory.create())
        .build();

//prepare image file
File file = new File(imagePath);
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
MultipartBody.Part imageFileBody = MultipartBody.Part.createFormData("image", file.getName(), requestBody);

YourAPI service = retrofit.create(YourAPI.class);
Call<Response> call = service.uploadImage(imageFileBody);
call.enqueue(new Callback<Response>() {
    @Override
    public void onResponse(Call<Response> call, Response<Response> response) {
        //handle success
    }

    @Override
    public void onFailure(Call<User> call, Throwable t) {
        //handle error
    }
}
ikhsanudinhakim
  • 1,554
  • 16
  • 23
  • Thankyou, But my question is that i have to pass this multipart file in a json . Buts its not working if i pass MultipartBody.Part as a Gson object. as shown in the json. – Nivedh Jun 13 '16 at 09:29
  • I don't actually understand your question. If you want to send your object as a json it will be possible by serializing your Object to json string. – ikhsanudinhakim Jun 13 '16 at 09:36
  • I need to pass this Multipart object inside a tag "profile_image_attributes" in the above json format. – Nivedh Jun 13 '16 at 09:45
0

You can send Multipart File along with JSON as string in RequestBody. Here's an example of sending multiple images with JSON. This is how your service method should look like

@Multipart
@POST("/addCountry")
fun addCountry(@Part images: List<MultipartBody.Part>,@Part("country") country:RequestBody):Call<String>

And while calling the retrofit api

val image= mutableListOf<MultipartBody.Part>()
        images.forEach {
            image.add(MultipartBody.Part.
                        createFormData(
                            "images",
                            it.name,
                            RequestBody.create(MediaType.parse("image/*"),it)
                        )
                    )
        }
val reqBody=RequestBody.create(MediaType.parse("text/plain"),json)
val call = APIClient.CountryAPI.addCountry(image,reqBody)

The 'json' variable is string which stores the JSON of your object. You can use Gson to convert your object into JSON.

Raghav Sharma
  • 43
  • 1
  • 6