Micronaut 自定义验证器未触发

问题描述 投票:0回答:1

我无法让自定义验证器在我的对象上触发。内置约束似乎有效(例如大小),但 myy

@UniqueUsername
似乎没有触发。谁能告诉我出了什么问题吗?

import groovy.transform.CompileStatic
import io.micronaut.core.annotation.AnnotationValue
import io.micronaut.core.annotation.NonNull
import io.micronaut.core.annotation.Nullable
import io.micronaut.validation.validator.constraints.ConstraintValidator
import io.micronaut.validation.validator.constraints.ConstraintValidatorContext
import jakarta.inject.Inject
import jakarta.inject.Singleton
import jakarta.validation.Constraint
import jakarta.validation.Payload

import java.lang.annotation.Documented
import java.lang.annotation.ElementType
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
import java.lang.annotation.Target

@Documented
@Target([ElementType.FIELD, ElementType.PARAMETER])
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = [])
@interface UniqueUsername {
    String message() default "Username is already taken."
    Class<?>[] groups() default [ ]
    Class<? extends Payload>[] payload() default []
}

@Singleton
@CompileStatic
class UniqueUsernameValidator implements ConstraintValidator<UniqueUsername, String> {
    @Inject
    UserRepository userRepository

    @Override
    boolean isValid(@Nullable String value, @NonNull AnnotationValue<UniqueUsername> annotationMetadata, @NonNull ConstraintValidatorContext context) {
        if (userRepository.countByUsername(value) > 0) {
            return false
        }

        return true
    }
}
import groovy.transform.CompileStatic
import io.micronaut.http.HttpRequest
import io.micronaut.http.HttpResponse
import io.micronaut.http.MediaType
import io.micronaut.http.annotation.*
import io.micronaut.security.annotation.Secured
import io.micronaut.security.rules.SecurityRule
import io.micronaut.serde.annotation.Serdeable
import io.micronaut.views.View
import jakarta.validation.ConstraintViolationException
import jakarta.validation.Valid
import jakarta.validation.constraints.Email
import jakarta.validation.constraints.NotBlank
import jakarta.validation.constraints.NotNull
import jakarta.validation.constraints.Size

@Secured(SecurityRule.IS_ANONYMOUS)
@Controller('/register')
@CompileStatic
class RegisterController {

    final UserRepository userRepository
    final RegisterService registerService

    RegisterController(UserRepository userRepository, RegisterService registerService) {
        this.userRepository = userRepository
        this.registerService = registerService
    }

    @View('auth/register')
    @Get
    Map<String, Object> registration() {
        return Collections.emptyMap()
    }

    @View('auth/register')
    @Error(exception = ConstraintViolationException)
    Map<String, Object> constraintViolation(HttpRequest request, ConstraintViolationException exception) {
        return ['errors': true] as Map<String, Object>
    }

    @Post
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    HttpResponse registerUser(@Valid @Body RegistrationForm registrationForm) {

        registerService.register(registrationForm.email, registrationForm.username, registrationForm.password)
        HttpResponse.ok()
    }
}

@Serdeable
@PasswordsMatch
class RegistrationForm {
    @Email
    @NotBlank
    @NotNull
    String email

    @NotBlank
    @NotNull
    @Size(max=50)
    @UniqueUsername
    String username

    @NotBlank
    @NotNull
    String password

    @NotBlank
    @NotNull
    String confirmPassword

    boolean doPasswordsMatch() {
        return password == confirmPassword
    }
}

编辑

我尝试按照建议更改为使用

@Factory
,但这似乎也不适合我。

import groovy.util.logging.Slf4j
import io.micronaut.context.annotation.Factory
import io.micronaut.validation.validator.constraints.ConstraintValidator
import jakarta.inject.Inject
import jakarta.inject.Singleton

@Slf4j
@Factory
class ConstraintValidatorFactory {

    @Inject
    UserRepository userRepository

    @Singleton
    ConstraintValidator<UniqueUsername, String> uniqueUsernameValidator() {
        log.info("uniqueUsernameValidator called")
        return (value, annotationMetadata, context) -> {
            value && !userRepository.countByUsername(value)
        }
    }

    @Singleton
    ConstraintValidator<PasswordsMatch, RegistrationForm> passwordsMatchValidator() {
        return (value, annotationMetadata, context) -> (value.password == value.confirmPassword)
    }
}
groovy bean-validation micronaut
1个回答
0
投票

结果我的 build.gralde 文件丢失了

implementation("io.micronaut.validation:micronaut-validation")

一旦我添加了这一点,我的约束就开始起作用了。

© www.soinside.com 2019 - 2024. All rights reserved.