【问题标题】:Retrofit requestbody using @FieldMap使用@FieldMap 改造请求体
【发布时间】:2020-07-14 03:07:04
【问题描述】:

我需要通过 Http 请求发送一个大型数据类。 这是我的课:

data class User(
    val uid: String,
    val mobNum: String,
    val isValidated: Boolean,
    val isActivated: Boolean,
    val gender: String,
   ...
   ...
   ...)

这是我用于更新部分数据的 Api 服务。如果需要。

internal interface ProfileApi {    
    @POST("update/profile")
    @FormUrlEncoded
    fun updatePending(
        @Field("_id") uid: String,
        @Field("mobile_num")  mobNum: String,
        @Field("is_validated") isValidated: Boolean,
        @Field("is_activated") isActivated: Boolean,
        @Field("gender") gender: String,
        .....
        ....
    ): Call<ResponseClass>
}

但这次我需要发送所有 50 个或更多字段的请求。如何使用 @FieldMap 或任何其他方法将数据键映射到字段键和相应的值。 谢谢。

【问题讨论】:

    标签: android kotlin retrofit2


    【解决方案1】:

    参考 -> How to post array in retrofit android

    @FormUrlEncoded
    @POST("service_name") 
       void functionName(
            @FieldMap Map<String, String> learning_objective_uuids, @FieldMap Map<String, String> user_uuids, @Field("note") String note,
            Callback<CallBackClass> callback
        );
    

    @FormUrlEncoded
        @POST("service_name") 
           void functionName(
                @Field("learning_objective_uuids[]") ArrayList<String> learning_objective_uuids, @Field("user_uuids[]") ArrayList<String> user_uuids, @Field("note") String note,
                Callback<CallBackClass> callback
            );
    

    【讨论】:

    • 我想我需要先将我的应用程序特定字段映射到 api 特定字段。那是怎么回事?
    • 创建映射,然后输入键值,对所有字段名执行相同的操作,然后映射到函数中。
    【解决方案2】:

    这是解决方法.. 创建一个新类: refer this

    data class UserMap(
        val _id: String,
        val mobile_num: String,
        val is_validated: Boolean,
        val is_activated: Boolean,
        val gender: String
    ){
        object ModelMapper {
            fun from(user: User) =
                UserMap(user.uid,user.mobNum, user.isValidated, user.isActivated, user.gender)}
    

    使用这个映射器(只需用它创建一个 kt 文件)将 UserMap 类映射到 Maprefer this

    val gson = Gson()
    
    //convert a data class to a map
    fun <T> T.serializeToMap(): Map<String, Any> {
        return convert()
    }
    
    //convert a map to a data class
    inline fun <reified T> Map<String, Any>.toDataClass(): T {
        return convert()
    }
    
    //convert an object of type I to type O
    inline fun <I, reified O> I.convert(): O {
        val json = gson.toJson(this)
        return gson.fromJson(json, object : TypeToken<O>() {}.type)
    }
    

    然后在你想传递数据的地方像这样使用:

    val userMap = UserMap.ModelMapper.from(User).serializeToMap() 
    

    现在将 userMap 传递给接口:

    @JvmSuppressWildcards
    internal interface MatchesApi {
    
        @POST("update/profile")
        @FormUrlEncoded
        fun updatePending(
            @FieldMap userMap: Map<String, Any>
        ):Call<ResponseClass>
    }
    

    不要忘记使用@JvmSuppressWildcards 进行注释,否则会遇到retrofit2 throws parameterError(Parameter type must not include a type variable or wildcard) 错误。 玩得开心。

    【讨论】:

    • 太棒了,你获得了这种享受
    猜你喜欢
    • 1970-01-01
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    • 2020-06-14
    相关资源
    最近更新 更多