How to send Form data in retrofit2 android
finally i found the solution hope this will help some other
i achieve the solution by using FieldMap
of retrofit.
@POST("initiate")@FormUrlEncodedCall<UserInfoServerResponse> getUserInfoRequest(@FieldMap Map<String,String> params);
and in the Rest Adaptor section i changed request data from string to Hashmap form like following
Log.d(TAG, "sendUserInfo called");UserInfo mInfo = new UserInfo("countyname","android");String request = new Gson().toJson(mUserInfo);// Here the json data is add to a hash map with key dataMap<String,String> params = new HashMap<String, String>();params.put("data", request);Call<UserInfoServerResponse> api = mService.getUserInfoRequest(params);api.enqueue(new Callback<UserInfoServerResponse>() { @Override public void onResponse(Call<UserInfoServerResponse> responseCall, Response<UserInfoServerResponse> response) { if (response.body().status != null) { if (response.body().status.equals("success")) { Log.d(TAG, "success---" + response.body()); } } else { Log.d(TAG, "Failed---"); } } @Override public void onFailure(Call<UserInfoServerResponse> responseCall, Throwable t) { t.printStackTrace(); }});
Basilcally what I used @FormUrlEncoded for form data and @FieldMap to put my request JSON as a key value. i got solution by following this method, hope this will help some one :)
The above solution works but is cumbersome to use , a better solution will be to use a converter for @Multipart formData
Please use the bellow code for proceeding with @Multipart FormDataThis is because
import java.io.IOException;import java.lang.annotation.Annotation;import java.lang.reflect.Type;import okhttp3.MediaType;import okhttp3.RequestBody;import okhttp3.ResponseBody;import retrofit2.Converter;import retrofit2.Retrofit;/** * Created by kural on 10/27/17. */public class StringConverterFactory extends Converter.Factory {private static final MediaType MEDIA_TYPE = MediaType.parse("text/plain");public static StringConverterFactory create() { return new StringConverterFactory(); }@Overridepublic Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { if (String.class.equals(type)) { return new Converter<ResponseBody, String>() {@Overridepublic String convert(ResponseBody value) throws IOException { return value.string(); } }; } return null; }@Overridepublic Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { if (String.class.equals(type)) { return new Converter<String, RequestBody>() { @Override public RequestBody convert(String value) throws IOException { return RequestBody.create(MEDIA_TYPE, value); } }; } return null;}}
and in your retrofit client add this line
.addConverterFactory(StringConverterFactory.create())
public class RetroFitClient { private static Retrofit retrofit = null; public static Retrofit getClient(String baseUrl) { if (retrofit==null) { HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build(); /*retrofit = new Retrofit.Builder() .baseUrl(baseUrl) .client(client) .addConverterFactory(GsonConverterFactory.create()) .build();*/ retrofit = new Retrofit.Builder() .baseUrl(baseUrl) .client(client) .addConverterFactory(StringConverterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build(); } return retrofit; }
This works fine for me and return a json to obtain new valid Microsoft Azure Token :
My end point :
@PostMapping(value = "/get-new-token", consumes = {"application/JSON"}, produces = {"application/JSON"})@Timedpublic ResponseEntity<String> getNewToken(@RequestBody String refreshToken) throws IOException { JSONObject json = tokenService.getNewTokenByRefreshToken(refreshToken); return new ResponseEntity<>(json.toString(), HttpStatus.OK);}
My getGraphRepository :
public GraphRepository getGraphRepository() { HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient client = new OkHttpClient.Builder() .addInterceptor(interceptor).build(); // Create and configure the Retrofit object Retrofit retrofit = new Retrofit.Builder() .baseUrl(" https://login.microsoftonline.com") .client(client) .addConverterFactory(JacksonConverterFactory.create()) .build(); // Generate the graph repo return retrofit.create(GraphRepository.class);}
My Token Service :
public JSONObject getNewTokenByRefreshToken(String refreshToken) throws IOException { GraphRepository graphRepository = getGraphRepository(); // My list of -> Key : Value Map<String,String> params = new HashMap<String, String>(); params.put("grant_type", "refresh_token"); params.put("client_id", this.client_id); params.put("client_secret", client_secret); params.put("refresh_token", refreshToken); RefreshToken data = graphRepository.getRefreshToken(tenantId, params).execute().body(); JSONObject json = new JSONObject(data); return json;}
My GraphRepository :
@POST("/{tenant_id}/oauth2/v2.0/token")@FormUrlEncodedCall<RefreshToken> getRefreshToken( @Path("tenant_id") String tenant_id, @FieldMap Map<String, String> params);
I hope this can help someone.