改造可选和必填字段

Retrofit optional and required fields

使用 Retrofit 时,我知道您可以使用 @FieldMap Map<String, String> options 指定可选查询。

假设我有一个 api 调用,它有 2 个必填字段和 3 个可选字段。

如何格式化这些调用?

会不会像

Call<Response> getStuff(@Query("user_id") String userId, @Query("password") String password, @FieldMap Map<String, String> options)

或者整个事情会是一个单一的@FieldMap,比如:

Call<Response> getStuff(@FieldMap Map<String, String> options)

如果使用此选项,您是否只需填写必填字段,然后使用 null 作为选项?

@FieldMap@Query 参数都支持可选字段。正如您提到的,如果您不想传递值,只需传递 null

Retrofit2(与 Retrofit1 不同)不接受 @FiledMap 中的空值(抛出异常)。 传递给 @Field/@Query 参数的空值被忽略(不出现在 http 请求中)

我在问题上卡了几个小时,终于解决了问题。

我将使用 Kotlin 来回答这个问题。

正如@Ryan 所说,您也可以将 null 作为 Kotlin 中的值传递:

fun getStuff(@Query("user_id") userId: String? = null ,
                 @Query("password") password: String? = null,
                 @FieldMap options: Map<String, String>? = null): Call<Response>

如果您在 Java 中有像 @Query("page") int page 这样的可选字段,您应该记住以下几点:

在Java中,您不能为intfloatlong等原始数据类型传递null

相反,使用IntegerFloatLong等,编译器就不会脾气暴躁了。

所以正确答案是:@Query("page") Integer page.

并且在 Kotlin 中,您不能为 IntFloatLong 等原始数据类型传递 null

使用 Int? 而不是 Int,Retrofit 将在组装请求时忽略它们。

这是因为当 Kotlin 在 JVM 上编译时,此类型的不可空值表示为基本类型 int 的值,可空值如 Int? 是装箱类型。

那么在 Kotlin 中,一个可为 null 的 Int Int?可以解决这个问题。

有关 Kotlin 原语的更多信息,请参阅:

我希望它也对某些人有所帮助。

是的,ryan 说的没错。

在 java 中,您的调用示例将是:

Call<Response> getStuff(null,null,@FieldMap Map<String, String> options);

记住这将与“字符串”完美配合 如果您想将“int”或“float”保留为可选,请不要使用原始数据类型,如 int、float、long 等。相反,请使用 Integer、Float、Long 等
所以你的带有可选整数和浮点数的例子将是:

Call<Response> getStuff(@Query("user_id") Integer userId, @Query("password") Float password, @FieldMap Map<String, String> options);

此语法将采用跳过整数值(如果需要,在服务器端处理)。