是的,我知道已经晚了,但有人可能会从中受益。
使用改造2:
昨晚我从 Volley 迁移到 Retrofit2 时遇到了这个问题(正如 OP 所说,这是内置在 Volley 中的JsonObjectRequest
),尽管Jake 的答案是 Retrofit1.9 的正确答案,但 Retrofit2 没有TypedString
。
我的案例需要发送一个Map<String,Object>
可能包含一些空值的,转换为 JSONObject (不会与 一起飞行@FieldMap
,特殊字符也不会,有些会被转换),因此遵循@bnorms 提示,并如Square所述:
可以使用 @Body 注释指定一个对象用作 HTTP 请求正文。
该对象也将使用 Retrofit 实例上指定的转换器进行转换。如果不添加转换器,则只能使用 RequestBody。
所以这是一个使用RequestBody
and的选项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 {
@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())
}