英文:
How to apply custom validation on a field using javax validation only if it is not null?
问题
我正在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 UniqueUser {
String message() default "User id already exists";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
UniqueUserValidator.java
public class UniqueUserValidator implements ConstraintValidator<UniqueUser, 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;
}
}
在上述代码中,即使用户名字段为null,唯一用户验证也会被调用,并显示“用户名已存在”错误消息。我希望只有在用户名具有某些值时才调用自定义验证器。是否有可能避免这种调用。
我可以通过修改下面的方法来修复错误,如果用户名为null,则返回true,但我想避免这种不必要的调用。
public class UniqueUserValidator implements ConstraintValidator<UniqueUser, 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;
}
}
英文:
I am working on javax validation API in Spring Boot Application. I have a User bean and i have to validate that username given in request is unique and doesn't exist into Database.
I have created custom annotation (UniqueUser.java
) and custom Validator(UniqueUserValidator.java
) for this requirement.
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;
}
}
In above code, the unique user validation get called for username field even if the field is null and shows Username already exists error message. I want the custom validator to get called only when username has some value. Is it possible to avoid this call.
I can fix the error by modifying the below method and returning true if username is null, but i want't to avoid this unnecessary call.
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;
}
}
答案1
得分: 1
我认为您要寻找的是分组约束;
> 分组允许您在验证期间限制应用的约束集。验证组的一个用例是 UI 向导,在每个步骤中只需要验证指定的一部分约束。目标组以 var-arg 参数的形式传递给适当的验证方法。
在您的情况下,应该是这样的:
@GroupSequence({ FirstConstaint.class, SecondConstaint.class })
public class User {
@NotNull(groups = FirstConstaint.class)
@UniqueUser(groups = SecondConstaint.class)
private String username;
// 其他字段
}
interface FirstConstaint {
}
interface SecondConstaint {
}
这样,它只会在字段不为空时检查 @UniqueUser
,否则,它将返回 @NotNull
验证的消息。
另外,如 @User 所说,您还可以将这些检查用于服务层 ^^
英文:
I think what you are looking for is Grouping constraints;
> Groups allow you to restrict the set of constraints applied during
> validation. One use case for validation groups are UI wizards where in
> each step only a specified subset of constraints should get validated.
> The groups targeted are passed as var-arg parameters to the
> appropriate validate method.
In your case it should look like this:
@GroupSequence({ FirstConstaint.class, SecondConstaint.class })
public class User {
@NotNull(groups = FirstConstaint.class)
@UniqueUser(groups = SecondConstaint.class)
private String username;
// the rest of your fields
}
interface FirstConstaint {
}
interface SecondConstaint {
}
This way, it will check @UniqueUser
only if the field is not null, otherwise, it will return the message of @NotNull validation.
Otherwise like @User said you can use this checks in service layer ^^
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论