Retrofit 是否支持将 JSON 作为参数传递,但将其作为普通参数调用?
Does Retrofit support passing JSON as parameter, yet call it as normal parameters?
背景
在对服务器的某些 API 调用中,而不是接口的正常参数,如下所示:
interface SomeInterface {
@POST("first_launch") fun sendFirstLaunch(
@Path("referral_code") referralCode: String?,
@Path("referral_source") referralSource: String?): Call<BaseDCResponse>
}
我们实际上需要在正文中将这些参数作为 JSON 发送。
问题
我不是Retrofit专家,但是根据我的发现(例如here),我只能向接口传递一个Json字符串,意思是:
interface SomeInterface {
@POST("first_launch") fun sendFirstLaunch(@Body jsonString: String): Call<BaseDCResponse>
}
根据 here,我相信我也可以发送序列化对象。意思是这样的:
interface SomeInterface {
class SendFirstLaunchRequest(@Path("referral_code") val referralCode: String?,
@Path("referral_source") val referralSource: String?)
@POST("first_launch") fun sendFirstLaunch(
@Body body: SendFirstLaunchRequest): Call<BaseDCResponse>
}
这失去了到达功能的好方法,同时让我为我放在界面上的每个功能手动添加 Json 数据(或创建新的 类 以传递到那里)。我想避免这个,和原来的类似。
我试过的
我试图搜索更多相关信息,但似乎没有人要求这样做。
也许我看到了答案,但没看懂。
我想连官方网站都显示了一些线索:
https://square.github.io/retrofit/
看到我觉得不可能,我也加了一个要求here。
问题
Retrofit 是否允许将我设置的参数发送到函数,作为一个 Json 数据作为主体?
如果没有,有什么好的解决方法吗?我是否正确,我只能传递一个序列化对象?如果是这样,正确的方法是什么?也许喜欢 here?
使用 Retrofit2:
昨晚我在从 Volley 迁移到 Retrofit2 时遇到了这个问题(正如 OP 所述,这是使用 JsonObjectRequest 内置到 Volley 中的),尽管 Jake 的回答对于 Retrofit1.9 是正确的,但 Retrofit2 却不是有 TypedString.
我的情况需要发送一个 Map ,它可能包含一些空值,转换为 JSONObject(不会与@FieldMap 一起飞行,特殊字符也不会,有些会被转换),所以跟随@ bnorms 提示,正如 Square 所述:
可以使用 @Body 注释指定一个对象作为 HTTP 请求主体。
该对象也将使用 Retrofit 实例上指定的转换器进行转换。如果不添加转换器,则只能使用RequestBody。
所以这是一个使用 RequestBody 和 ResponseBody 的选项:
在你的界面中使用 @Body 和 RequestBody
public interface ServiceApi
{
@POST("Your api end point")
Call<ResponseBody> login(@Header("X_API_KEY") String header, @Body RequestBody body);
}
在您的调用点创建一个 RequestBody,说明它是 MediaType,并使用 JSONObject 将您的地图转换为正确的格式:
Map<String, Object> jsonParams = new ArrayMap<>();
//put something inside the map, could be null
jsonParams.put("name", 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(header, 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...
}
});
希望这对任何人都有帮助!
似乎没有,有人请求提供一些东西来帮助处理这个问题:
背景
在对服务器的某些 API 调用中,而不是接口的正常参数,如下所示:
interface SomeInterface {
@POST("first_launch") fun sendFirstLaunch(
@Path("referral_code") referralCode: String?,
@Path("referral_source") referralSource: String?): Call<BaseDCResponse>
}
我们实际上需要在正文中将这些参数作为 JSON 发送。
问题
我不是Retrofit专家,但是根据我的发现(例如here),我只能向接口传递一个Json字符串,意思是:
interface SomeInterface {
@POST("first_launch") fun sendFirstLaunch(@Body jsonString: String): Call<BaseDCResponse>
}
根据 here,我相信我也可以发送序列化对象。意思是这样的:
interface SomeInterface {
class SendFirstLaunchRequest(@Path("referral_code") val referralCode: String?,
@Path("referral_source") val referralSource: String?)
@POST("first_launch") fun sendFirstLaunch(
@Body body: SendFirstLaunchRequest): Call<BaseDCResponse>
}
这失去了到达功能的好方法,同时让我为我放在界面上的每个功能手动添加 Json 数据(或创建新的 类 以传递到那里)。我想避免这个,和原来的类似。
我试过的
我试图搜索更多相关信息,但似乎没有人要求这样做。
也许我看到了答案,但没看懂。
我想连官方网站都显示了一些线索:
https://square.github.io/retrofit/
看到我觉得不可能,我也加了一个要求here。
问题
Retrofit 是否允许将我设置的参数发送到函数,作为一个 Json 数据作为主体?
如果没有,有什么好的解决方法吗?我是否正确,我只能传递一个序列化对象?如果是这样,正确的方法是什么?也许喜欢 here?
使用 Retrofit2:
昨晚我在从 Volley 迁移到 Retrofit2 时遇到了这个问题(正如 OP 所述,这是使用 JsonObjectRequest 内置到 Volley 中的),尽管 Jake 的回答对于 Retrofit1.9 是正确的,但 Retrofit2 却不是有 TypedString.
我的情况需要发送一个 Map
可以使用 @Body 注释指定一个对象作为 HTTP 请求主体。
该对象也将使用 Retrofit 实例上指定的转换器进行转换。如果不添加转换器,则只能使用RequestBody。
所以这是一个使用 RequestBody 和 ResponseBody 的选项:
在你的界面中使用 @Body 和 RequestBody
public interface ServiceApi
{
@POST("Your api end point")
Call<ResponseBody> login(@Header("X_API_KEY") String header, @Body RequestBody body);
}
在您的调用点创建一个 RequestBody,说明它是 MediaType,并使用 JSONObject 将您的地图转换为正确的格式:
Map<String, Object> jsonParams = new ArrayMap<>();
//put something inside the map, could be null
jsonParams.put("name", 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(header, 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...
}
});
希望这对任何人都有帮助!
似乎没有,有人请求提供一些东西来帮助处理这个问题: