Проверка вложенных объектов в spring MVC
У меня есть проблема с проверкой вложенного объекта. Я имею в виду, что у меня есть регистрационная форма, где предоставляется командный объект, который выглядит следующим образом
краткая версия:
public class RegistrationObject { private User user; @NotEmpty @Size(min = 5, message = "{password.size}") @Pattern(regexp = "^.*(?=.{8,})(?=.*\\d)(?=.*[a-zA-Z])|(?=.{8,})(?=.*\\d)(?=.*[!@#$%^&])|(?=.{8,})(?=.*[a-zA-Z])(?=.*[!@#$%^&]).*$", message= "{password.strength}") private String repeatPass; public RegistrationObject() { } public RegistrationObject(User user, String repeatPass) { this.user = user; this.repeatPass = repeatPass; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public String getRepeatPass() { return repeatPass; } public void setRepeatPass(String repeatPass) { this.repeatPass = repeatPass; } }
В моем контроллере я размещаю объект и использую @Valid соответственно, он проверяет пароль, но пользовательский объект не проверяется. Он переходит в службу и пытается быть сохраненным, что приводит к ошибке проверки. Что хорошо, это показывает, что ограничения работают, но проверка должна быть выполнена во время отправки формы.
Вопрос в том, почему он не проверяет пользователя и каков хороший способ сделать такую проверку?
Вот пользователь, метод контроллера для post и пользовательский валидатор
@Entity @Table(name = "user") public class User extends BaseEntity implements UserDetails { @NotEmpty @Size(min = 5, max = 16, message = "{username.size}") private String username; @NotEmpty @Size(min = 5, message = "{password.size}") @Pattern(regexp = "^.*(?=.{8,})(?=.*\\d)(?=.*[a-zA-Z])|(?=.{8,})(?=.*\\d)(?=.*[!@#$%^&])|(?=.{8,})(?=.*[a-zA-Z])(?=.*[!@#$%^&]).*$", message= "{password.strength}") private String password; @NotEmpty @Email(message = "{email.valid}") private String email; @NotEmpty @Size(min = 5, max = 16, message = "{firstName.size}") private String firstName; @NotEmpty @Size(min = 5, max = 16, message = "{lastName.size}") private String lastName; @NotNull private int age; private boolean enabled; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "user") private Collection<Authorities> authorities = new ArrayList<>();
Контроллер
@RequestMapping(value = "/signup", method = RequestMethod.POST) public String register(@Valid @ModelAttribute("regObject") RegistrationObject regObject, BindingResult result) throws PasswordNotMatchException { if (result.hasErrors()) { return "registration/signup"; } userService.register(regObject); return "redirect:/helloworld/home"; }
@Component("registrationValidator") public class RegistrationValidator implements Validator { private UserService userService; @Autowired public RegistrationValidator(UserService userService) { this.userService = userService; } @Override public boolean supports(Class<?> aClass) { return RegistrationObject.class.equals(aClass); } @Override public void validate(Object obj, Errors errors) { ValidationUtils.rejectIfEmptyOrWhitespace(errors, "user.password", "password.empty"); ValidationUtils.rejectIfEmptyOrWhitespace(errors, "repeatPass", "password.empty"); RegistrationObject regObj = (RegistrationObject) obj; if (!regObj.getUser().getPassword().equals(regObj.getRepeatPass())) { errors.rejectValue("repeatPass", "password.notMatch"); } User user = userService.findByUsername(regObj.getUser().getUsername()); if (user != null && (user.getUsername().equals(regObj.getUser().getUsername()))) { errors.rejectValue("username", "username.unique"); } } }
Что я уже пробовал:
Я попробовал изменить метод контроллера, удалив пользовательский валидатор, что не идеально и не помогло. Также пробовал добавлять @действительна для регистрации объекта пользователя, как
@Действительного пользователя
Ни один из них не сработал.