【发布时间】:2020-07-26 14:18:52
【问题描述】:
我正在开发 Spring Boot 应用程序中的 javax 验证 API。我有一个用户 bean,我必须验证请求中给出的用户名是唯一的,并且不存在于数据库中。
我为此要求创建了自定义注释 (UniqueUser.java) 和自定义验证器(UniqueUserValidator.java)。
public class User {
@NotNull
@UniqueUser
private String username;
@NotNull
private String password;
@NotNull
@Email
private String email;
@NotNull
private String phone;
}
UniqueUser.java
@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = UniqueUserValidator.class)
@Documented
public @interface NameMatch
{
String message() default "User id already exists";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
UniqueUserValidator.java
public class UniqueUserValidator implements ConstraintValidator<NameMatch, Object>
{
@Autowired
UserRepository userRepository;
@Override
public boolean isValid(String userName, final ConstraintValidatorContext context)
{
boolean isValidUser = false;
if(userName!=null && !userName.isEmpty()) {
Optional<User> user= userRepository.findByUserId(userName);
isValidUser = !user.isPresent();
}
return isValidUser;
}
}
在上面的代码中,即使用户名字段为空并显示用户名已存在错误消息,也会为用户名字段调用唯一用户验证。我希望仅当用户名具有某些值时才调用自定义验证器。是否可以避免此调用。
我可以通过修改下面的方法来修复错误,如果用户名为空则返回 true,但我不想避免这种不必要的调用。
public class UniqueUserValidator implements ConstraintValidator<NameMatch, Object>
{
@Autowired
UserRepository userRepository;
@Override
public boolean isValid(String userName, final ConstraintValidatorContext context)
{
boolean isValidUser = false;
if(userName!=null && !userName.isEmpty()) {
Optional<User> user= userRepository.findByUserId(userName);
isValidUser = !user.isPresent();
} else {
isValidUser = true;
}
return isValidUser;
}
}
【问题讨论】:
-
你是说你不想打电话给
if(userName!=null && !userName.isEmpty())? -
如果您不签入
isValid,那么您必须在某处检查 null 以做出决定,那么实际上没有任何优化。您当前的实现很好 -
而是使用我喜欢使用的自定义注释在服务内部进行此检查,因为您在控制器之前调用存储库,这根本不是一个好的模式,恕我直言。
-
附注:我认为您的意思是
public @interface UniqueUser,因为您在 DTO 中使用@UniqueUser
标签: java spring-boot validation hibernate-validator