验证spring MVC中的嵌套对象 [英] Validating nested objects in spring MVC
问题描述
我在验证嵌套对象时遇到了问题。我的意思是我有一个注册表单,其中提供了一个看起来像这样的命令对象
短版本:
public class RegistrationObject {
私人用户用户;
@NotEmpty
@Size(min = 5 ,message = {password.size})
@Pattern(regexp =
^ *(= {8,}?)(= * \\d?)(= * [A-ZA-Z])|。?。(= {8 ?,})(= * \\d)(= * [@#$%^&安培;!])|(= {8})(= * [A-ZA-。?。?。?。 Z])(?=。* [!@#$%^&])。* $,
message = < span class =code-string> {password.strength})
private String repeatPass;
public RegistrationObject(){
}
public RegistrationObject(用户用户,字符串 repeatPass){
此 .user =用户;
此 .repeatPass = repeatPass;
}
public 用户getUser(){
return user;
}
public void setUser(用户用户){
此 .user = user;
}
public String getRepeatPass(){
return repeatPass;
}
public void setRepeatPass( String repeatPass){
this .repeatPass = repeatPass;
}
}
在我的控制器中我发布对象并使用@Valid相应地,它验证密码,但没有验证User对象。它转到服务并尝试持久化,这会引发验证错误。哪个好,它表明约束有效,但验证需要在表单提交期间进行。
问题是,为什么它没有验证用户,以及进行这种验证的好方法是什么?
以下是发布的用户,控制器方法和自定义验证器
@ Entity
@ Table (name = user)
public class 用户 extends BaseEntity implements UserDetails {
< span class =code-sdkkeyword> @ 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 密码;
@ NotEmpty
@ Email (message = {email.valid})
private String 电子邮件;
@ 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 年龄;
private boolean 已启用;
@ OneToMany (cascade = CascadeType.ALL,fetch = FetchType.EAGER,mappedBy = user)
private Collection< Authorities> authorities = new ArrayList<>();
控制器
@ RequestMapping (value = / signup,method = RequestMethod.POST)
public < span class =code-sdkkeyword> String register( @ Valid @ ModelAttribute (< span class =code-string> regObject)RegistrationObject regObject,BindingResult result) throws PasswordNotMatchException {
if (result.hasErrors()){
return 注册/注册;
}
userService.register(regObject);
return redirect:/ helloworld / home 跨度>;
}
@Component ( registrationValidator)
public class RegistrationValidator implements Validator {
< span class =code-keyword> private UserService userService;
@Autowired
public RegistrationValidator(UserService userService){
< span class =code-keyword> this .userService = userService;
}
@覆盖
public boolean 支持(Class<?> aClass){
return RegistrationObject。类跨度> .equals(ACLASS);
}
@覆盖
public void validate(对象obj,错误错误){
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(< span class =code-string> repeatPass, password.notMatch跨度>);
}
用户user = userService.findByUsername(regObj.getUser()。getUsername());
if (user!= null&&(user.getUsername()。equals(regObj.getUser()。getUsername()))){
errors.rejectValue( username, username.unique);
}
}
}
我尝试了什么:
我尝试更改控制器方法,删除自定义验证器,这是不理想的,没有帮助。还尝试将@Valid添加到注册对象用户,例如
@Valid用户用户
他们都没有工作。
%^&])|(?=。{8,})(?=。* [a-zA-Z])(?=。* [!@#
%^&])。*
,
message = {password.strength})
private 字符串 repeatPass;
public RegistrationObject(){
}
public RegistrationObject(用户用户,字符串 repeatPass){
this .user = user;
this .repeatPass = repeatPass;
}
public 用户getUser(){
返回用户;
}
public void setUser(用户用户){
此 .user = user;
}
public String getRepeatPass(){
return repeatPass;
}
public void setRepeatPass( String repeatPass){
this .repeatPass = repeatPass;
}
}
在我的控制器中我发布对象并使用@Valid相应地,它验证密码,但没有验证User对象。它转到服务并尝试持久化,这会引发验证错误。哪个好,它表明约束有效,但验证需要在表单提交期间进行。
问题是,为什么它没有验证用户,以及进行这种验证的好方法是什么?
以下是发布的用户,控制器方法和自定义验证器
@ Entity
@ Table (name = user)
public class 用户 extends BaseEntity implements UserDetails {
< span class =code-sdkkeyword> @ NotEmpty
@ Size (min = 5 ,max = 16 ,message = { username.size})
privateString username;
@ NotEmpty
@ Size (min = 5 ,message = {password.size})
@ Pattern (regexp = ^。*(? 。= {8})(= * \\d)(= * [A-ZA-Z])|????(= {8,})(= * \\ d)(?=。* [!@#
I have an issue validating a nested object. What I mean by this is that I have a registration form, where a command object is provided that looks like this
short version:
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;
}
}
In my controller I post the object and use @Valid accordingly, it validates the password, but the User object is not being validated. It goes to the service and attempts to be persisted, which throws a validation error. Which is fine, it shows that the constraints work, but validation needs to be happen during form submission.
The question is, why it is not validating the User, and what is a good way to do this kind of validation?
Here are the user, controller method for post and the custom validator
@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<>();
Controller
@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");
}
}
}
What I have tried:
I tried changing the controller method, removing custom validator, which is not ideal and didn't help. Also tried adding @Valid to the registration object user like
@Valid User user
None of them worked.
%^&])|(?=.{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; } }
In my controller I post the object and use @Valid accordingly, it validates the password, but the User object is not being validated. It goes to the service and attempts to be persisted, which throws a validation error. Which is fine, it shows that the constraints work, but validation needs to be happen during form submission.
The question is, why it is not validating the User, and what is a good way to do this kind of validation?
Here are the user, controller method for post and the custom validator
@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)(?=.*[!@#
这篇关于验证spring MVC中的嵌套对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!