我正在尝试验证用户注册。场景很常见:如果用户名或电子邮件存在,则应用程序必须通知用户哪个字段被违反(唯一约束)。到目前为止,我已经完成了以下操作: 该方法处理注册。基本上我尝试提交事务(插入),如果失败,则用 try catch 捕获异常。
@RequestMapping(value = "/registration", method = RequestMethod.POST)
public ModelAndView createNewUser(@Valid User user, BindingResult bindingResult) {
ModelAndView modelAndView = new ModelAndView();
try{
userService.saveUser(user);
modelAndView.addObject("successMessage", "User has been registered successfully");
modelAndView.addObject("user", user);
modelAndView.setViewName("registration");
}catch(DataIntegrityViolationException e){
bindingResult
.rejectValue("email", "error.user",
"There is already a user registered with the email provided");
}
return modelAndView;
}
这是我的模型类:
@Entity
@Table(name = "users")
public class User implements Serializable{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="user_id")
private Long user_id;
@Column(name="username")
@NotEmpty(message = "*Username is required")
@Length(min = 5, max = 20, message = "*Your username can have min 5 and max 20 characters")
private String username;
@Column(name="password")
@NotEmpty(message = "*Password is reqired")
@Transient
private String password;
@Column(name="email")
@Email(message = "*Please provide a valid Email")
@NotEmpty(message = "*Email is required")
private String email;
@Column(name="enabled")
private int enabled;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getEnabled() {
return enabled;
}
public void setEnabled(int enabled) {
this.enabled = enabled;
}
public Long getUser_id() {
return user_id;
}
public void setUser_id(Long user_id) {
this.user_id = user_id;
}
}
这是我的注册页面:
<form autocomplete="off" action="#" th:action="@{/registration}"
th:object="${user}" method="post" class="form-horizontal"
role="form">
<h2>Registration Form</h2>
<div class="form-group">
<div class="col-sm-9">
<label th:if="${#fields.hasErrors('username')}" th:errors="*{username}"
class="validation-message"></label>
<input type="text" th:field="*{username}" placeholder="Username"
class="form-control" />
</div>
</div>
<div class="form-group">
<div class="col-sm-9">
<input type="text" th:field="*{email}" placeholder="Email"
class="form-control" /> <label
th:if="${#fields.hasErrors('email')}" th:errors="*{email}"
class="validation-message"></label>
</div>
</div>
<div class="form-group">
<div class="col-sm-9">
<input type="password" th:field="*{password}"
placeholder="Password" class="form-control" /> <label
th:if="${#fields.hasErrors('password')}" th:errors="*{password}"
class="validation-message"></label>
</div>
</div>
<div class="form-group">
<div class="col-sm-9">
<button type="submit" class="btn btn-primary btn-block">Register User</button>
</div>
</div>
<span th:utext="${successMessage}"></span>
</form>
问题。现在的问题是,在我的 createNewUser 方法中,我确实 try catch 。当发生唯一违规时,catch block 会处理它。但如果存在多个违规行为:用户名和电子邮件怎么办?如何从异常中获取哪个字段被违反并将其与正确的表单字段关联?
最佳答案
我想说您需要添加自己的自定义 validator 来检查唯一的用户名和电子邮件。
代码摘自下面的示例。 @Unique(service = UserService.class, fieldName = "email", message = "{email.unique.violation}") 私有(private)字符串电子邮件;
注释和 validator
@Target({ METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = UniqueValidator.class)
@Documented
public @interface Unique {
String message() default "{unique.value.violation}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
Class<? extends FieldValueExists> service();
String serviceQualifier() default "";
String fieldName();
}
和
public class UniqueValidator implements ConstraintValidator<Unique, Object> {
@Autowired
private ApplicationContext applicationContext;
private FieldValueExists service;
private String fieldName;
@Override
public void initialize(Unique unique) {
Class<? extends FieldValueExists> clazz = unique.service();
this.fieldName = unique.fieldName();
String serviceQualifier = unique.serviceQualifier();
if (!serviceQualifier.equals("")) {
this.service = this.applicationContext.getBean(serviceQualifier, clazz);
} else {
this.service = this.applicationContext.getBean(clazz);
}
}
@Override
public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
return !this.service.fieldValueExists(o, this.fieldName);
}
}
关于java - Spring,从异常中获取多个模型违规,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44250097/