Went to upgrade to Retrofit 2.0 and running into this weird problem.
I have a method to log a user in
public interface ApiInterface {
@Multipart
What about to do in that way?
RequestBody caption = RequestBody.create(MediaType.parse("text/plain"), new String("caption"));
If your UI is showing your responses with quotes, you can use getAsString
instead of toString
Here is how to resolve it,
Firstly:
return new Retrofit.Builder()
.baseUrl(Env.GetApiBaseUrl())
.addConverterFactory(new GsonStringConverterFactory())
.addConverterFactory(GsonConverterFactory.create(gson))
.client(getHttpClient())
.build();
Create a CustomConverter like this one, this is needed by Retrofit 2, unless some fix the "feature" added in v2.
public class GsonStringConverterFactory extends Converter.Factory {
private static final MediaType MEDIA_TYPE = MediaType.parse("text/plain");
@Override
public Converter<?, RequestBody> toRequestBody(Type type, Annotation[] annotations) {
if (String.class.equals(type))// || (type instanceof Class && ((Class<?>) type).isEnum()))
{
return new Converter<String, RequestBody>() {
@Override
public RequestBody convert(String value) throws IOException {
return RequestBody.create(MEDIA_TYPE, value);
}
};
}
return null;
}
}
I've found another one solution except those. Worked with Retrofit 2.1.0. (Rx adapter is optional here)
My retrofit interface looks like this:
@POST("/children/add")
Observable<Child> addChild(@Body RequestBody requestBody);
And in ApiManager I use it like this:
@Override
public Observable<Child> addChild(String firstName, String lastName, Long birthDate, @Nullable File passportPicture) {
MultipartBody.Builder builder = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("first_name", firstName)
.addFormDataPart("last_name", lastName)
.addFormDataPart("birth_date", birthDate + "");
//some nullable optional parameter
if (passportPicture != null) {
builder.addFormDataPart("certificate", passportPicture.getName(), RequestBody.create(MediaType.parse("image/*"), passportPicture));
}
return api.addChild(builder.build());
}
It is similar to Solution1 from Loyea but I think that it's little a bit more elegant.
I have the same problem, and how it solved:
1) Add to build.gradle:
compile 'com.squareup.retrofit2:converter-scalars:2.1.0' // Remember to add the same version
2) Add one line here:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(URL_BASE)
.addConverterFactory(ScalarsConverterFactory.create()) // this line
.addConverterFactory(GsonConverterFactory.create(gson))
.client(getUnsafeOkHttpClient())
.build();
I don't know if it is too late, but we can also send requests with RequestBody.
Example:
public interface ApiInterface {
@Multipart
@POST("user/login/")
Call<SessionToken> userLogin(@Part("username") String username, @Part("password") String password);
}
We can convert as below:
public interface ApiInterface {
@Multipart
@POST("user/login/")
Call<SessionToken> userLogin(@Part("username") RequestBody username, @Part("password") String password);
}