是的,我知道已经晚了,但是有人可能会从中受益。
使用Retrofit2:
昨晚我从Volley迁移到Retrofit2时遇到了这个问题(并且正如OP所述,它是在Volley中内置的JsonObjectRequest
),尽管Jake的答案是Retrofit1.9的正确答案,但Retrofit2却没有TypedString
。
我的情况要求发送一个Map<String,Object>
可能包含一些空值的,将其转换为JSONObject(不会使用@FieldMap
,特殊字符也不会转换,有些会被转换),因此遵循@bnorms提示,如Square所述:
可以使用@Body注释将对象指定为HTTP请求正文。
该对象还将使用Retrofit实例上指定的转换器进行转换。如果未添加转换器,则只能使用RequestBody。
因此,这是使用RequestBody
和的选项ResponseBody
:
在你的界面使用@Body
与RequestBody
public interface ServiceApi
{
@POST("prefix/user/{login}")
Call<ResponseBody> login(@Path("login") String postfix, @Body RequestBody params);
}
在您的调用点中,创建一个RequestBody
,指出它是MediaType,然后使用JSONObject将您的Map转换为正确的格式:
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...
}
});
希望这对任何人有帮助!
上面的优雅Kotlin版本,允许从其余应用程序代码中的JSON转换中提取参数:
interface ServiceApi {
fun login(username: String, password: String) =
jsonLogin(createJsonRequestBody(
"username" to username, "password" to password))
@POST("/api/login")
fun jsonLogin(@Body params: RequestBody): Deferred<LoginResult>
private fun createJsonRequestBody(vararg params: Pair<String, String>) =
RequestBody.create(
okhttp3.MediaType.parse("application/json; charset=utf-8"),
JSONObject(mapOf(*params)).toString())
}