我使用
ConstraintValidator
实现了自定义密码验证,并且我需要在验证失败时显示错误消息。但验证失败时不会显示错误消息。
界面:
@Target({FIELD})
@Retention(RUNTIME)
@Constraint(validatedBy = {PasswordConstraintValidator.class})
@Documented
public @interface Password {
String message() default "{messages.validation.password}";
int maxLength() default 100;
int minLength() default 8;
int upperCaseCount() default 2;
int lowerCaseCount() default 2;
int specialCharCount() default 1;
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
实施
@Component
public class PasswordConstraintValidator implements ConstraintValidator<Password, String> {
private int minLength;
private int maxLength;
private int upperCaseCount;
private int lowerCaseCount;
private int specialCharCount;
@Override
public void initialize(final Password password) {
minLength = password.minLength();
maxLength = password.maxLength();
upperCaseCount = password.upperCaseCount();
lowerCaseCount = password.lowerCaseCount();
specialCharCount = password.specialCharCount();
}
@Override
public boolean isValid(final String string, final ConstraintValidatorContext constraintValidatorContext) {
return validatePassword(string);
}
// method validatePassword(string){}
我的注册表如下所示:
<form xmlns:th="http://www.thymeleaf.org" th:action="@{/register/user}" method="post"
th:object="${userDto}" style="width: 22rem;" th:fragment="reg-user-form">
<!-- Password -->
<div class="form-outline mb-4">
<label class="form-label text-white h5" for="password" th:text="#{label.password}">Password</label>
<input type="password" id="password" th:field="*{password}" class="form-control bg-dark text-white rounded border-2" style="border-color: #2f3944;" required />
<div class="text-danger" th:if="${#fields.hasErrors('password')}" th:errors="*{password}"></div>
</div>
</form>
控制器方法如下所示:
@GetMapping(USER_REGISTER_URL)
public String regUser(final Model model) {
model.addAttribute("userDto", new RequestUserDto());
return USER_REGISTER_PAGE;
}
@PostMapping(USER_REGISTER_URL)
public String regUser(@Valid @ModelAttribute final RequestUserDto userDto,
final BindingResult bindingResult, final Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("userDto", userDto);
model.addAttribute("errors", bindingResult.getAllErrors());
return USER_REGISTER_PAGE;
}
userService.createUser(userDto);
return LOGIN_PAGE_REDIRECT;
}
我通过用
bindingResult
打印出来来检查
System.out.println
中是否有错误
Field error in object 'requestUserDto' on field 'password': rejected value [awdsaw]; codes [Password.requestUserDto.password,Password.password,Password.java.lang.String,Password]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [requestUserDto.password,password]; arguments []; default message [password],2,100,8,1,2]; default message [The Password is incorrect. Max length of password - 100, min length of password 8, must contain: upper case—at least 2, lower case - at least 2, special char - 1]
但是,Thymeleaf 不会显示错误消息,这种情况不仅会发生在自定义验证中,还会发生在像
@Size:
这样的注释中
Field error in object 'requestUserDto' on field 'firstName': rejected value [a]; codes [Size.requestUserDto.firstName,Size.firstName,Size.java.lang.String,Size]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [requestUserDto.firstName,firstName]; arguments []; default message [firstName],50,10]; default message [size must be between 10 and 50]
尝试更新到此:
<div class="text-danger" th:text="${errors}"></div>