Yes I know it's late, but somebody would probably benefit from this.
Using Retrofit2:
I came across this problem last night migrating from Volley to Retrofit2 (and as OP states, this was built right into Volley with JsonObjectRequest
), and although Jake's answer is the correct one for Retrofit1.9, Retrofit2 doesn't have TypedString
.
My case required sending a Map<String,Object>
that could contain some null values, converted to a JSONObject (that won't fly with @FieldMap
, neither does special chars, some get converted), so following @bnorms hint, and as stated by Square:
An object can be specified for use as an HTTP request body with the @Body annotation.
The object will also be converted using a converter specified on the Retrofit instance. If no converter is added, only RequestBody can be used.
So this is an option using RequestBody
and ResponseBody
:
In your interface use @Body
with RequestBody
public interface ServiceApi
{
@POST("prefix/user/{login}")
Call<ResponseBody> login(@Path("login") String postfix, @Body RequestBody params);
}
In your calling point create a RequestBody
, stating it's MediaType, and using JSONObject to convert your Map to the proper format:
Map<String, Object> jsonParams = new ArrayMap<>();
//put something inside the map, could be null
jsonParams.put("code", some_code);
RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"),(new JSONObject(jsonParams)).toString());
//serviceCaller is the interface initialized with retrofit.create...
Call<ResponseBody> response = serviceCaller.login("loginpostfix", body);
response.enqueue(new Callback<ResponseBody>()
{
@Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> rawResponse)
{
try
{
//get your response....
Log.d(TAG, "RetroFit2.0 :RetroGetLogin: " + rawResponse.body().string());
}
catch (Exception e)
{
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable throwable)
{
// other stuff...
}
});
An elegant Kotlin version of the above, to allow abstracting the parameters from the JSON convertion in the rest of your application code:
interface ServiceApi {
@POST("/api/login")
fun jsonLogin(@Body params: RequestBody): Deferred<LoginResult>
}
class ServiceApiUsingClass {
//ServiceApi init
fun login(username: String, password: String) =
serviceApi.jsonLogin(createJsonRequestBody(
"username" to username, "password" to password))
private fun createJsonRequestBody(vararg params: Pair<String, String>) =
RequestBody.create(
okhttp3.MediaType.parse("application/json; charset=utf-8"),
JSONObject(mapOf(*params)).toString())
}
RequestBody
like this ->RequestBody body = RequestBody.create(MediaType.parse("text/plain"), text);
for detailed answer futurestud.io/tutorials/… – Bennie