Kotlin中的数据验证:库概览与实践示例
数据验证是构建可靠应用程序的关键方面之一。在Kotlin生态系统中,有多个强大的库允许您声明式地描述验证规则,避免冗长的条件结构。在本文中,我们将介绍三种流行的工具:Konad、Valiktor和Kvalidation。您将了解它们的工作原理,并看到针对实际任务的代码示例。
1. Konad — 函数式验证
Konad (Kotlin Validation) 使用单子(monad)和函数式编程的概念。该库不抛出异常,而是返回 Validated<E, A>,其中 E 是错误类型,A 是成功值。这允许累积错误并无副作用地处理它们。
安装
// build.gradle.ktsdependencies { implementation("io.github.mkobit:konad:0.3.0")}使用示例
import konad.*
data class User(val name: String, val age: Int)
fun validateUser(user: User): Validated<String, User> { return Validated.valid(user) .validate { it.name.isNotBlank() } { "Name cannot be blank" } .validate { it.age in 18..99 } { "Age must be between 18 and 99" }}
fun main() { val user = User("Alice", 25) val result = validateUser(user)
when (result) { is Valid -> println("Valid user: ${result.value}") is Invalid -> println("Errors: ${result.errors.joinToString(", ")}") }}Konad 的优势:
- 无异常的纯函数式风格
- 累积所有验证错误
- 验证器的组合
2. Valiktor — 声明式验证与流畅 API
Valiktor 提供了一种直观的 DSL 来描述规则。该库支持嵌套对象、集合和自定义错误消息。这是 Kotlin 最流行的工具之一。
安装
// build.gradle.ktsdependencies { implementation("org.valiktor:valiktor-core:0.12.0")}嵌套对象示例
import org.valiktor.*import org.valiktor.functions.*
data class Address(val city: String, val zip: String)data class Person(val name: String, val email: String, val address: Address)
fun validatePerson(person: Person) { validate(person) { validate(Person::name).isNotBlank().hasSize(min = 2, max = 50) validate(Person::email).isEmail() validate(Person::address) { validate(Address::city).isNotBlank() validate(Address::zip).matches("\\\\d{5}".toRegex()) } }}
fun main() { val person = Person("", "invalid-email", Address("", "123")) try { validatePerson(person) } catch (e: ConstraintViolationException) { e.constraintViolations.forEach { violation -> println("${violation.property}: ${violation.message}") } }}Valiktor 的特点:
- 完全支持嵌套对象和列表
- 本地化的错误消息
- 与 Spring Boot 和 Ktor 集成
3. Kvalidation — 基于注解的模块化验证
Kvalidation(原名 Koptional)提供注解式和程序化两种方法。该库特别适用于检查 REST API 中的输入数据。
安装
// build.gradle.ktsdependencies { implementation("com.willowtreeapps:kvalidation:1.0.0")}注解示例
import com.willowtreeapps.kvalidation.annotations.*import com.willowtreeapps.kvalidation.Validator
data class Product( @field:NotBlank(message = "Pro