如何验证POJO数据类通过GSON解析Firestore数据时的映射正确性
解决方案
方案1:Data Class 内置初始化校验(最小改动,适合中小项目)
直接在数据类的init代码块集中定义所有必填字段的校验规则,Gson反序列化生成对象时会自动执行校验逻辑,不合法直接抛出异常,无需后续逐个判断:
data class Users( val id: String = "", val userID: String = "", val optionalField: String? = null // 可空字段无需校验 ) { init { // 所有必填字段统一在这里加校验,新增必填字段仅需新增一行规则 require(id.isNotBlank()) { "id 字段不能为空或空串" } require(userID.isNotBlank()) { "userID 字段不能为空或空串" } } }
使用时捕获反序列化阶段抛出的异常即可判断数据合法性:
val parseData = try { gson.fromJson(jsonObjects, Users::class.java) } catch (e: IllegalArgumentException) { // 数据非法,直接返回失败 return false } // 后续直接使用合法对象即可
方案2:自定义Gson TypeAdapter(适合不想修改POJO类的场景)
自定义反序列化适配器,在解析JSON的阶段直接校验字段是否存在、是否合法,不合法直接终止解析抛出异常:
class UsersTypeAdapter : TypeAdapter<Users>() { override fun write(out: JsonWriter, value: Users) { // 序列化逻辑按需实现,仅用于解析的场景可空实现 } override fun read(`in`: JsonReader): Users { val json = JsonParser.parseReader(`in`).asJsonObject // 校验必填字段 val id = json.get("id")?.asString ?: throw IllegalArgumentException("缺少id字段") val userID = json.get("userID")?.asString ?: throw IllegalArgumentException("缺少userID字段") if (id.isBlank() || userID.isBlank()) throw IllegalArgumentException("必填字段为空") // 读取可空字段 val optionalField = json.get("optionalField")?.asString return Users(id, userID, optionalField) } }
将适配器注册到Gson实例即可生效:
val gson = GsonBuilder() .registerTypeAdapter(Users::class.java, UsersTypeAdapter()) .create()
方案3:注解式批量校验(适合字段多、POJO类多的大型项目)
基于JSR-380 Bean Validation规范,用注解标记字段校验规则,通用工具类自动扫描所有注解完成校验,新增规则仅需加注解,无需修改校验逻辑:
- 给POJO字段加校验注解:
import jakarta.validation.constraints.NotBlank data class Users( @NotBlank(message = "id不能为空") val id: String = "", @NotBlank(message = "userID不能为空") val userID: String = "", val optionalField: String? = null )
- 实现通用校验工具类:
import jakarta.validation.Validation object POJOValidator { private val validator = Validation.buildDefaultValidatorFactory().validator fun <T> isValid(obj: T): Boolean { return validator.validate(obj).isEmpty() } }
- 解析后调用校验即可:
val parseData = gson.fromJson(jsonObjects, Users::class.java) if (!POJOValidator.isValid(parseData)) return false
额外优化建议
你当前先将Firestore快照数据转JSON再转POJO的操作存在冗余,Firestore SDK原生支持直接转对象:querySnapshot.toObject(Users::class.java),性能更高,上述所有校验规则同样生效。
内容的提问来源于stack exchange,提问作者lyncx
相关产品推荐
相关产品推荐

