spring - 如何在 thymeleaf View 上显示 beanValidation 类级别约束?

标签 spring groovy bean-validation thymeleaf

我正在使用 bean 验证(JSR303)来验证两个字段,这些字段使用注释和验证器进行验证,注释针对的类型意味着注释是我的 bean 的类级别约束。
问题是我如何表达我的观点的错误?
(我正在使用 groovy)
注册表:

package core.model

import core.validation.PasswordConfirmation
import core.validation.UniqueEmail
import core.validation.UniqueUsername
import groovy.util.logging.Slf4j
import org.hibernate.validator.constraints.Email
import org.hibernate.validator.constraints.NotBlank

import static core.model.AuthoritiesEnum.ROLE_USER

@Slf4j
@PasswordConfirmation
class SignupForm {

    static final String NOT_BLANK_MESSAGE = "{notBlank.message}"
    static final String UNIQUE_USERNAME_MESSAGE = "{uniqueUsername.message}"
    static final String EMAIL_MESSAGE = "{username.message}"
    static final String UNIQUE_EMAIL_MESSAGE = "{uniqueEmail.message}"

    @UniqueUsername
    @NotBlank(message = SignupForm.NOT_BLANK_MESSAGE)
    String username

    @UniqueEmail
    @NotBlank(message = SignupForm.NOT_BLANK_MESSAGE)
    @Email(message = SignupForm.EMAIL_MESSAGE)
    String email

    @NotBlank(message = SignupForm.NOT_BLANK_MESSAGE)
    String password

    @NotBlank(message = SignupForm.NOT_BLANK_MESSAGE)
    String confirmPassword


    User createAccount() {
        new User(username: email, email: email, password: password, role: ROLE_USER)
    }
}

PasswordConfirmation 验证注解:
package core.validation

import javax.validation.Constraint
import javax.validation.Payload
import java.lang.annotation.Retention
import java.lang.annotation.Target

import static java.lang.annotation.ElementType.TYPE
import static java.lang.annotation.RetentionPolicy.RUNTIME

@Target(TYPE)
@Retention(RUNTIME)
@Constraint(validatedBy = PasswordConfirmationValidator)
@interface PasswordConfirmation {

    String message() default "{core.signup.validation.passwordConfirmation.message}"

    Class<?>[] groups() default []

    Class<? extends Payload>[] payload() default []
}

密码确认验证器:
package core.validation

import core.model.SignupForm
import groovy.util.logging.Slf4j

import javax.validation.ConstraintValidator
import javax.validation.ConstraintValidatorContext

@Slf4j
class PasswordConfirmationValidator implements ConstraintValidator<PasswordConfirmation, SignupForm> {

    @Override
    void initialize(PasswordConfirmation constraintAnnotation) {
    }

    @Override
    boolean isValid(SignupForm form, ConstraintValidatorContext context) {
        log.info "password : ${form.password}"
        log.info "confirmPassword : ${form.confirmPassword}"
        println "password : ${form.password}"
        println "confirmPassword : ${form.confirmPassword}"
        println "defaultConstraintMessageTemplate : ${context.defaultConstraintMessageTemplate}"
        form.password.equals form.confirmPassword
    }
}

thymeleaf View signup.html :
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">

<head>
    <title th:text="#{view.signup.title}">Inscription</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <link href="../../../resources/css/bootstrap.min.css" rel="stylesheet" media="screen"
      th:href="@{/resources/css/bootstrap.min.css}"/>
    <link href="../../../resources/css/core.css" rel="stylesheet" media="screen" th:href="@{/resources/css/core.css}"/>
    <script src="http://code.jquery.com/jquery-latest.js"></script>
    <script src="../../../resources/js/bootstrap.min.js" th:src="@{/resources/js/bootstrap.min.js}"></script>
</head>

<body>

<div th:replace="fragments/header_signup :: header">Header</div>
<form class="form-narrow form-horizontal" method="post"
  th:action="@{/signup}" th:object="${signupForm}">
    <!-- /* Show general error message when form contains errors */ -->
    <th:block th:if="${#fields.hasErrors('${signupForm.*}')}">
        <div th:replace="fragments/alert :: alert (type='danger', message='Form contains errors. Please try again.')">
            Alert
        </div>
    </th:block>
    <fieldset>
        <div class="form-group" th:classappend="${#fields.hasErrors('username')}? 'has-error'">
            <label for="username" class="col-lg-2 control-label">Username</label>

            <div class="col-lg-10">
                <input type="text" class="form-control" id="username" placeholder="Username" th:field="*{username}"/>
                <span class="help-block" th:if="${#fields.hasErrors('username')}"
                  th:errors="*{username}">Incorrect username</span>
            </div>
        </div>
        <div class="form-group" th:classappend="${#fields.hasErrors('email')}? 'has-error'">
            <label for="email" class="col-lg-2 control-label">Email</label>

            <div class="col-lg-10">
                <input type="text" class="form-control" id="email" placeholder="Email address" th:field="*{email}"/>
                <span class="help-block" th:if="${#fields.hasErrors('email')}"
                  th:errors="*{email}">Incorrect email</span>
            </div>
        </div>
        <div class="form-group" th:classappend="${#fields.hasErrors('password')}? 'has-error'">
            <label for="password" class="col-lg-2 control-label">Password</label>

            <div class="col-lg-10">
                <input type="password" class="form-control" id="password" placeholder="Password"
                   th:field="*{password}"/>
                <span class="help-block" th:if="${#fields.hasErrors('password')}" th:errors="*{password}">Incorrect password</span>
            </div>
        </div>
        <div class="form-group" th:classappend="${#fields.hasErrors('confirmPassword')}? 'has-error'">
            <label for="confirmPassword" class="col-lg-2 control-label">Password confirmation</label>

            <div class="col-lg-10">
                <input type="password" class="form-control" id="confirmPassword" placeholder="Password confirmation"
                   th:field="*{confirmPassword}"/>
                <!--how to show classe level constraint validation-->
                <span class="help-block" th:if="${#fields.hasErrors('confirmPassword')}" th:errors="*{confirmPassword}">Incorrect password confirmation</span>
            </div>
        </div>
        <div class="form-group">
            <div class="col-lg-offset-2 col-lg-10">
                <button type="submit" class="btn btn-default" th:text="#{view.signup.label}">Sign up</button>
            </div>
        </div>
    </fieldset>
</form>
</body>
</html>

最佳答案

为了显示类级别的约束消息,我成功地使用了全局常量,就像在 documentation 中所示的更新的 html 代码中一样。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <title th:text="#{view.signup.title}">Inscription</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <link href="../../../resources/css/bootstrap.min.css" rel="stylesheet" media="screen"
      th:href="@{/resources/css/bootstrap.min.css}"/>
    <link href="../../../resources/css/core.css" rel="stylesheet" media="screen" th:href="@{/resources/css/core.css}"/>
    <script src="http://code.jquery.com/jquery-latest.js"></script>
    <script src="../../../resources/js/bootstrap.min.js" th:src="@{/resources/js/bootstrap.min.js}"></script>
</head>
<body>
<div th:replace="fragments/header_signup :: header">Header</div>
<form class="form-narrow form-horizontal" method="post"
  th:action="@{/signup}" th:object="${signupForm}">
    <!-- /* Show general error message when form contains errors */ -->
    <th:block th:if="${#fields.hasErrors('${signupForm.*}')}">
        <div th:replace="fragments/alert :: alert (type='danger', message='Form contains errors. Please try again.')">
        Alert
        </div>
    </th:block>
    <fieldset>
        <div class="form-group" th:classappend="${#fields.hasErrors('username')}? 'has-error'">
            <label for="username" class="col-lg-2 control-label">Username</label>

            <div class="col-lg-10">
                <input type="text" class="form-control" id="username" placeholder="Username" th:field="*{username}"/>
                <span class="help-block" th:if="${#fields.hasErrors('username')}"
                  th:errors="*{username}">Incorrect username</span>
            </div>
        </div>
        <div class="form-group" th:classappend="${#fields.hasErrors('email')}? 'has-error'">
            <label for="email" class="col-lg-2 control-label">Email</label>

            <div class="col-lg-10">
                <input type="text" class="form-control" id="email" placeholder="Email address" th:field="*{email}"/>
                <span class="help-block" th:if="${#fields.hasErrors('email')}"
                  th:errors="*{email}">Incorrect email</span>
            </div>
        </div>
        <div class="form-group" th:classappend="${#fields.hasErrors('password')}? 'has-error'">
            <label for="password" class="col-lg-2 control-label">Password</label>

            <div class="col-lg-10">
                <input type="password" class="form-control" id="password" placeholder="Password"
                   th:field="*{password}"/>
                <span class="help-block" th:if="${#fields.hasErrors('password')}" th:errors="*{password}">Incorrect password</span>
            </div>
        </div>
        <div class="form-group" th:classappend="${#fields.hasErrors('confirmPassword')}? 'has-error'">
            <label for="confirmPassword" class="col-lg-2 control-label">Password confirmation</label>

            <div class="col-lg-10">
                <input type="password" class="form-control" id="confirmPassword" placeholder="Password confirmation"
                   th:field="*{confirmPassword}"/>
                <span class="help-block" th:if="${#fields.hasErrors('confirmPassword')}" th:errors="*{confirmPassword}">Incorrect password confirmation</span>
                <span class="help-block" th:if="${#fields.hasErrors('global')}" th:errors="*{global}">Incorrect password confirmation</span>
            </div>
        </div>
        <div class="form-group">
            <div class="col-lg-offset-2 col-lg-10">
                <button type="submit" class="btn btn-default" th:text="#{view.signup.label}">Sign up</button>
            </div>
        </div>
    </fieldset>
</form>
</body>
</html>

关于spring - 如何在 thymeleaf View 上显示 beanValidation 类级别约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25657411/

相关文章:

java - 有没有办法将 @Scheduled 与 Duration 字符串(如 15s 和 5m)一起使用?

sql - 来自 grails 项目的 hibernate AssertionFailure

java - Heroku - 致命 : password authentication failed for user <>

java - 无法将 ID 从 gsp 传递到 Controller

java - 包 Javax.portlet 不存在

java - 如何将@ConvertGroup与@GroupSequenceProvider一起使用

java - JSR-303/Spring MVC - 使用组进行条件验证

spring-mvc - 具有容器元素约束的Kotlin数据类和bean验证

java - MessageSource bean 在自定义异常映射器类中注入(inject) null

java - 如何写出好的删除数据的方法来纠正呢?