Android Retrofit POST请求中如何发送空HashMap对象?
解决方案
场景1:请求体为JSON格式(使用@Body注解传参)
serializeNulls()仅作用于值为null的字段,默认配置下Gson本就会将空Map序列化为{},如果配置后仍然不生效,可通过自定义Map类型适配器强制序列化空Map,配置代码如下:
val gsonNullSupport = GsonBuilder() .serializeNulls() // 注册Map类型的自定义适配器,强制空Map输出{} .registerTypeAdapter(object : TypeToken<Map<*, *>>() {}.type, object : TypeAdapter<Map<*, *>>() { override fun write(out: JsonWriter, value: Map<*, *>?) { // 空Map或者null的Map都输出{} if (value == null || value.isEmpty()) { out.beginObject() out.endObject() return } // 非空Map正常序列化 out.beginObject() value.forEach { (key, value) -> out.name(key.toString()) gsonNullSupport.toJson(value, value?.javaClass ?: Any::class.java, out) } out.endObject() } override fun read(`in`: JsonReader): Map<*, *> { return gsonNullSupport.fromJson(`in`, object : TypeToken<Map<*, *>>() {}.type) } }) .create() val gsonNullSupportConverterFactory = GsonConverterFactory.create(gsonNullSupport) // 确保GsonConverterFactory是第一个添加的Converter,避免被其他优先级更高的Converter覆盖 retrofitBuilder.addConverterFactory(gsonNullSupportConverterFactory)
场景2:表单格式请求(使用@FormUrlEncoded + @FieldMap注解)
该场景下Gson配置不会生效,表单参数由Retrofit内置的FormUrlEncodedConverter处理,默认会跳过空Map。你可以选择两种方案解决:
- 调整接口参数格式,改用
@Body传递整个请求体,让服务端接收JSON格式参数 - 单独把空Map对应的字段作为
@Field传递,手动赋值为"{}",示例如下:
@FormUrlEncoded @POST("你的接口路径") fun submitRequest( // 固定传空Map对应的{} @Field("你要传的Map对应的字段名") emptyMap: String = "{}", @FieldMap otherParams: Map<String, String> ): Call<你的响应类>
排查注意事项
- 确认Retrofit没有添加其他优先级更高的ConverterFactory(比如ScalarsConverterFactory、MoshiConverterFactory)在GsonConverterFactory之前,否则Gson配置不会生效
- 检查请求字段的
@SerializedName注解是否正确,和服务端要求的参数名是否匹配 - 接入OkHttp的LoggingInterceptor打印完整请求体,确认参数是否真的未被携带,排除后端接收逻辑的问题
内容的提问来源于stack exchange,提问作者Asad
相关产品推荐
相关产品推荐

