Retrofit中如何处理data class空数据,仅发送已填充的字段?
实现Retrofit请求仅携带data class主动赋值字段的方案
核心原理:该问题本质是JSON序列化时的字段过滤需求,仅序列化被主动修改过的字段、排除默认值字段即可实现需求。
方案1:修改字段为可空类型+默认null(最简便,语义更清晰)
可空类型可以明确区分「未传该参数」和「传了空字符串参数」两种业务场景,是最常用的实现方案:
- 修改data class定义,将字段设为可空类型,默认值设为null:
data class UserRequestDTO( val name: String? = null, val surname: String? = null )
- 安卓常用的Gson、Jackson序列化库默认都会忽略值为null的字段,不需要额外特殊配置,即可满足需求:
- 未赋值任何字段时,序列化结果为
{} - 仅赋值
name时,序列化结果为{"name": "赋值内容"}
小提示:你当前的请求调用代码未传入构造的
userDTO实例,需要修改为MyService.getService().users(userDTO)才能把参数传递给接口。
方案2:保留空字符串默认值,配置序列化规则
如果业务要求必须用空字符串作为默认值,可以通过配置序列化规则过滤空字符串字段:
针对Gson序列化场景
全局配置方式:
构建Gson实例时注册自定义排除策略:
class EmptyStringExclusionStrategy : ExclusionStrategy { override fun shouldSkipField(f: FieldAttributes): Boolean { // 排除值为空字符串的String类型字段 return f.declaredType == String::class.java && f.get(null) == "" } override fun shouldSkipClass(clazz: Class<*>?): Boolean = false } // 初始化Gson val gson = GsonBuilder() .setExclusionStrategies(EmptyStringExclusionStrategy()) .create() // Retrofit初始化时传入该Gson实例 val retrofit = Retrofit.Builder() .baseUrl("你的接口根地址") .addConverterFactory(GsonConverterFactory.create(gson)) .build()
单类注解方式(Gson 2.8+版本支持):
直接给需要过滤的data class加注解,不需要修改全局配置:
import com.google.gson.annotations.JsonInclude @JsonInclude(JsonInclude.Include.NON_EMPTY) data class UserRequestDTO( val name: String = "", val surname: String = "" )
NON_EMPTY规则会自动排除null、空字符串、空集合、0值等空状态字段。
针对Jackson序列化场景
给data class添加Jackson的JsonInclude注解即可:
import com.fasterxml.jackson.annotation.JsonInclude @JsonInclude(JsonInclude.Include.NON_EMPTY) data class UserRequestDTO( val name: String = "", val surname: String = "" )
如果需要全局生效,可以在初始化ObjectMapper时设置:
val objectMapper = ObjectMapper() .setSerializationInclusion(JsonInclude.Include.NON_EMPTY)
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

