0

I have a question which is we must use the javax validation as our validator in spring boot? Because I think it is quite troublesome if the business logic becomes more and complicated. And also, there is no order for the validation that make me have to create the group sequence for each input, and we need to create a custom annotation to validate if need to compare the input like the password and confirm password.

Here is my code

Actually, I'm wondering whether I did the javax validation in the wrong way. Please correct me if you guys discover the problem.

@Data
@NoArgsConstructor
@AllArgsConstructor
@ConfirmPassword(groups =  ConfirmPasswordGroup.ConfirmPasswordSecond.class)
public class UsersEntityDTO {

        public int id;

        @NotBlank(message ="Username is required", groups = UsernameGroup.UsernameFirst.class)
        @Size(min = 6, max = 15, message = "Username must be more than 5 characters and less than 16", groups = UsernameGroup.UsernameSecond.class)
        @Pattern.List({
                @Pattern(regexp = "^\\S*$", message = "Username cannot contain any whitespaces and special characters", groups = UsernameGroup.UsernameThird.class),
                @Pattern(regexp = "^[A-Za-z0-9 ]+$", message = "Username cannot contain any whitespaces and special characters", groups = UsernameGroup.UsernameFourth.class)
        })
        @UniqueUsername(groups = UsernameGroup.UsernameFifth.class)
        public String username;

        @NotBlank(message ="FullName is required", groups = FullnameGroup.FullnameFirst.class)
        @Size(min = 6, max = 70, message = "FullName must be more than 5 characters and less than 71", groups = FullnameGroup.FullnameSecond.class)
        @Pattern(regexp = "^[a-zA-Z ]*$", message = "FullName cannot contain any special characters and digits", groups = FullnameGroup.FullnameThird.class)
        public String fullname;

        @NotBlank(message ="Phone is required", groups = PhoneGroup.PhoneFirst.class)
        @Size(min = 10, max = 11, message = "Please enter a correct phone number", groups = PhoneGroup.PhoneSecond.class)
        @Pattern(regexp = "^[0-9]*$", message = "Phone number must only be digits", groups = PhoneGroup.PhoneThird.class)
        public String phone;

        @NotBlank(message ="Email is required", groups = EmailGroup.EmailFirst.class)
        @Email(message = "Please enter a correct email", groups = EmailGroup.EmailSecond.class)
        @UniqueEmail(groups = EmailGroup.EmailThird.class)
        public String email;

        @NotBlank(message ="Address is required", groups = AddressGroup.AddressFirst.class)
        @Size(min = 20, max = 250, message = "Address must be more than 20 characters and less than 250", groups = AddressGroup.AddressSecond.class)
        public String address;

        @NotBlank(message ="Password is required", groups = PasswordGroup.PasswordFirst.class)
        @Size(min = 6, message = "Password must be more than 5 characters", groups = PasswordGroup.PasswordSecond.class)
        public String password;

        @NotBlank(message ="Confirm Password is required", groups = ConfirmPasswordGroup.ConfirmPasswordFirst.class)
        public String confirmPassword;

        public String token;

        @NotBlank(message ="Status is required", groups = ConfirmPasswordGroup.ConfirmPasswordFirst.class)
        @StatusName(groups = ConfirmPasswordGroup.ConfirmPasswordSecond.class)
        public String status;
        public Date registration_date;

}

And the last thing is could I create the if else statement as our validator under the controller? I think this is more flexible and easier.

Jack Noob
  • 47
  • 1
  • 6

1 Answers1

0

For more complex logic, you can implement your own validator like

import org.springframework.validation.Validator;
public class PasswordValidator implements Validator {

@Override
    public boolean supports(Class<?> clazz) {
        return UsersEntityDTO.class.equals(clazz);
    }
    

@Override
    public void validate(Object target, Errors errors) {

        UsersEntityDTO user = (UsersEntityDTO) target;
        
        if(user.getPassword()==null || user.getPassword().trim().equals("")) {
            errors.rejectValue("password", "user.password.empty");
        }
    //other complex scenarios like whether password matches existing password etc.

}

Then in controller, whichever way you prefer, call validator like

passwordValidator.validate(user, bindingResult);
if(bindingResult.hasErrors()) {
//error
}

This way, your validation logic will be separated from Controller (Single responsibility)

Chetan Ahirrao
  • 1,454
  • 11
  • 16