我无法让自定义验证器在我的对象上触发。内置约束似乎有效(例如大小),但 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)
}
}
结果我的 build.gralde 文件丢失了
implementation("io.micronaut.validation:micronaut-validation")
一旦我添加了这一点,我的约束就开始起作用了。