Retrofit 2 with only form-data

I am trying to make POST request using the Retrofit 2. The request type is form-data NOT application/x-www-form-urlencoded.

I am only posting data not the files in the request and the response is in the form of JSON.

I have tried @FormUrlEncoded, @Multipart but it is not working.

I have tried following request

1. First Attempt

@FormUrlEncoded
@POST("XXXX")
Call<PlanResponse> getPlanName(@Field(Constants.ACTION_ID) String actionId, @Field(Constants.OFFER_CODE) String offerCode);

2. Second Attempt

@Headers({"Content-Type: multipart/form-data","Content-Type: text/plain"})
@FormUrlEncoded
@POST("XXXX")
Call<PlanResponse> getPlans(@Body @FieldMap(encoded = false) Map<String, String> data);

3. Third Attempt

@Headers("Content-Type: multipart/form-data")
@Multipart
@POST("XXXX")
Call<PlanResponse> myPlans(@Part(Constants.ACTION_ID) String actionId, @Part(Constants.OFFER_CODE) String offerCode);

I am only getting the body as null. It is working with the POSTMAN.

I have also search about form-data and application/x-www-form-urlencoded and found that if the data is binary then use form-data and if data is ASCII then use application/x-www-form-urlencoded

I am trying find Is form-data is not supported by the Retrofit?

POSTMAN request

Cache-Control: no-cache
Postman-Token: XXXXXXXXXXXX-XXXXXXXXXXXX-XXXXXXXXXXXX-XXXXXXXXXXXX-XXXXXXXXXXXX
Content-Type: multipart/form-data; boundary=----    WebKitFormBoundaryXXXXXXXXXXXX


 ----WebKitFormBoundaryXXXXXXXXXXXX
Content-Disposition: form-data; name="actionId"

1000
 ----WebKitFormBoundaryXXXXXXXXXXXX
Content-Disposition: form-data; name="offerCode"

MYCODE
----WebKitFormBoundaryXXXXXXXXXXXX

I can only add HTTP Generated code snipped from POSTMAN


Solution 1:

Here's another Solution using request body:

RequestBody requestBody = new MultipartBody.Builder()
        .setType(MultipartBody.FORM)
        .addFormDataPart("param1", param1)
        .addFormDataPart("param2", param2)
        .build();

apiInterface.somePostMethod(requestBody).enqueue(
    //onResponse onFailure methods
);

here's my api inteface POST method

@POST("somePostMethod")
Call<ResponseBody> somePostMethod(@Body RequestBody body);

Hope it helps.

Solution 2:

In retrofit 2.0 to perform POST request like above, you should use RequestBody type for your parameter like this.

@Multipart
@POST("XXXX")
Call<PlanResponse> myPlans(@Part(Constants.ACTION_ID) RequestBody actionId, @Part(Constants.OFFER_CODE) RequestBody offerCode);

And here how to get requestBody from String.

String somevalue = "somevalue";
RequestBody body = RequestBody.create(MediaType.parse("text/plain"), somevalue);