Spring Boot + Thymeleaf - 表单验证

标签 spring thymeleaf

我在验证表单时遇到 Thymeleaf 问题。我正在尝试创建简单的用户注册表来学习 Spring,但不幸的是我被卡住了。

这是我的 UserForm 类

public class UserForm {
    @NotEmpty
    private String username;
    @NotEmpty
    private String password;
    @NotEmpty
    private String passwordConfirm;

    \\ Getters and Setters
}

第一个问题是当我在 initBinder 中添加我的自定义验证器类时
@Autowired
private UserFormValidator formValidator;

@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.setValidator(formValidator);
}

@NotEmpty 验证注释的“默认”停止工作。这是预期的行为?

第二个问题是如何在 thymeleaf 中显示全局拒绝消息?
我的验证器类如下所示
public class UserFormValidator implements Validator {
    @Autowired
    UserService userService;

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

    @Override
    public void validate(Object target, Errors errors) {
        UserForm userForm = (UserForm) target;
        if(!userForm.getPassword().equals(userForm.getPasswordConfirm())) {
            errors.reject("passwords.no.match", "Passwords not match");
        }

        if(userService.findOneByUsername(userForm.getUsername()).isPresent()) {
            errors.reject("user.exist", "User already exists (default)");
        }
    }   
}

并从 Controller 发布映射
@PostMapping("/create")
public String registerUser(@ModelAttribute("form") @Valid final UserForm form, BindingResult bindingResult) {
    if(bindingResult.hasErrors()) {
        return "newuser";
    }
    userService.saveUser(form);
    return "redirect:/";
}

作为“默认”验证错误,我可以使用 exth:if="${#fields.hasErrors('passwordConfirm')}"我不知道如何显示错误 passwords.no.match 的消息或检查此错误发生?

最佳答案

默认情况下,spring boot 使用 bean 验证来验证用 @Valid 注释的表单对象。如果您想使用自定义验证器并通过@InitBinder 注册它,则不会进行 bean 验证,这是预期的行为。如果您希望 bean 验证也适用于您的自定义验证,您需要在验证器类中甚至在 Controller 中手动进行。

这是显示密码不匹配错误消息的第二个问题。在您的自定义验证器 UserFormValidator.class 中,同时拒绝您需要使用 rejectValue() 方法的任何值,如下所示:

    @Override
    public void validate(Object target, Errors errors) {
        UserForm userForm = (UserForm) target;
        if(!userForm.getPassword().equals(userForm.getPasswordConfirm())) {
            errors.rejectValue("passwordConfirm", "passwords.no.match", "Passwords not match");
        }

        if(userService.findOneByUsername(userForm.getUsername()).isPresent()) {
            errors.rejectValue("username", "user.exist", "User already exists (default)");
        }
    } 

rejectValue() 方法用于向 Errors 对象添加验证错误。
第一个参数标识错误与哪个字段相关联。第二个参数是一个错误代码,它作为messages.properties 文件(或messages_en.properties 或messages_fr.properties 等,如果它们正在被使用)的消息键。 rejectValue() 的第三个参数表示回退默认消息,如果在资源包中找不到匹配的错误代码,则显示该消息。

现在您可以使用 th:if="${#fields.hasErrors('passwordConfirm')} 显示错误消息在你的表格里面。

关于Spring Boot + Thymeleaf - 表单验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42423553/

相关文章:

spring - Spring启动服务器初始化后,抛出InvocationTargetException和ApplicationContextException

java - 尝试在 Thymeleaf Spring Boot 中迭代 List(<Object>) 时出现 "Exception evaluating SpringEL expression"错误

spring - Thymeleaf 3 和 Tiles2 集成

java - 如何在 Thymeleaf 中为每个循环显示对象集合?

xml - jQuery 或 Underscore.js 模板导致 thymeleaf 中的 XML 解析器错误

java - 如何使用 Thymeleaf 在 Java Spring 中创建简单表单

java - 使用 JSON、REST、Spring Boot JAVA POST 数据

Spring MVC - 从所有拦截器中排除 Assets

java - 依赖注入(inject): Spring and Java

java - 当抛出未经检查的异常时,异常处理程序是否有办法输出参数?