Каскадные проверки в Spring с использованием валидатора по умолчанию - PullRequest
0 голосов
/ 15 января 2019

Я делаю ручные проверки моих классов сущностей. Рассмотрим сущность человека:

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)
    }
}

Преимущество заключается в том, что я могу добавить этот валидатор к сервисам, которые планирую написать в будущем. Это работает хорошо, но давайте внесем изменения в класс person:

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

Теперь у нас есть класс работы, который принадлежит Person. У задания есть своя проверка.

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

То, что я хотел бы, это для моего валидатора, когда он вызывается и в классе Job. Это позволит логике валидации оставаться общей. Есть ли способ каскадной проверки вплоть до членов объекта, которые являются частью исходного класса, который называется

1 Ответ

0 голосов
/ 17 января 2019

Давайте начнем с рассмотрения следующего кода:

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() {
   ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...