使用默认验证器在Spring中进行级联验证

时间:2019-01-14 23:28:06

标签: java spring validation kotlin

我正在对实体类进行手动验证。考虑一个人实体:

data class Person (
    @get:NotNull var firstName: String = ""
) 

我的验证逻辑位于服务可以使用的抽象类中。

abstract class Validator {
    protected fun validate(model: Any): ValidationResult {
        val factory = Validation.buildDefaultValidatorFactory()
        val validator = factory.validator

        val validationResult = validator.validate(model).fold(ValidationResult()) { validationResult, violation ->
            val message = violation.propertyPath.toString() + " - " + violation.message
            validationResult.add(message)
            validationResult
        }

        // Raise a validation exeception
        if (validationResult.isValid()) {
            throw ValidationException(validationResult)
        }

        return validationResult
    }
}

这使我可以编写这样的服务。

class PersonService (): Validator() {
    fun save(person: Person) {
         validate(person)
         // more logic that assumes data is valid
         repository.save(person)
    }
}

优点是我可以将此验证器添加到我计划将来编写的服务中。效果很好,但是让我们更改人员类别:

data class Person (
    @get:NotNull var firstName: String = "",
    var job: Job = Job()
)

现在我们有一个属于Person的工作类别。 Job有自己的验证。

data class Job (
    @get:NotNull var department: String = "",
    @get:Min(0) var salary: Integer = "",
)

当在Job类上调用时,我想要的也是我的验证器。这将使验证逻辑保持通用。有什么方法可以将验证级联化为对象类,这些对象是被调用的原始类的一部分

1 个答案:

答案 0 :(得分:0)

让我们从下面的代码开始:

class PersonService (): Validator() {
    fun save(person: Person) {
         validate(person)
         // more logic that assumes data is valid
         repository.save(person)
    }
}

现在,我们将使用扩展方法将其重写:

class PersonService (): Validator() {
    fun save(person: Person) {
         person.validate()
         // more logic that assumes data is valid
         repository.save(person)
    }
}

此功能的存根可能看起来像这样:

private fun Person.validate() {
    val factory = Validation.buildDefaultValidatorFactory()
    val validator = factory.validator

    val validationResult = validator.validate(this).fold(ValidationResult()) { validationResult, violation ->
        val message = violation.propertyPath.toString() + " - " + violation.message
        validationResult.add(message)
        validationResult
    }

    // Raise a validation exeception
    if (validationResult.isValid()) {
        throw ValidationException(validationResult)
    }


    validationResult.addAll(job.validate())

    return validationResult
}

工作重复相同的模式:

private fun Job.validate() {
   ...
}