java - 使用 Thymeleaf 3.x 处理表单验证 - 样式化错误

标签 java spring spring-mvc web-applications thymeleaf

我第一次使用简单的 Web 应用程序测试 Thymeleaf 3.x,并且在进行表单验证时遇到了一些问题。我无法使用 Thymeleaf 属性 th:errorclass 更改表单字段的图形样式,我也不知道为什么。

这是我的 Controller :

@RequestMapping(value = {"/" , "" , "/home" , "/index" , "/login"} , method = RequestMethod.GET)
public String getLogin(final Model m)
{
    if(m.containsAttribute("login") == false)
    {
        System.out.println("Creating login form...");
        m.addAttribute("login", new For_Login());
    }

    return Util_Paginas.PAG_LOGIN.toString();
}

@RequestMapping(value = "/login" , method = RequestMethod.POST)
public String authenticate(
        @Valid @ModelAttribute("login") final For_Login form , 
        final BindingResult br , 
        final Model m)
{
    System.out.printf("Authentication received!%n");
    System.out.printf("LOGIN: %s%n" , form.getLogin());
    System.out.printf("PASS: %s%n" , form.getSenha());

    if(br.hasErrors())
    {
        System.out.printf("Found %d fields!%n" , br.getErrorCount());
    }

    return Util_Paginas.PAG_LOGIN.toString();
}

我的具有 Thymeleaf 3.x 性质的 HTML 文件:

<!DOCTYPE html>
<html>
    <head>
        <title>Login page</title>
        <link rel="stylesheet" type="text/css" media="all" th:href="@{/css/estilos.css}" />
    </head>

    <body>

        <p>Welcome. Please login.</p>

        <form action="#" th:action="@{/login}" th:object="${login}" method="post">
            <fieldset>
                <p>
                    Login: 
                    <input 
                    type="text" 
                    th:field="*{login}" 
                    th:class="campo" 
                    th:errorclass="campo-invalido">
                </p>
                <p>
                    Password: 
                    <input 
                    type="password" 
                    th:field="*{senha}" 
                    th:class="campo" 
                    th:errorclass="campo-invalido">
                </p>
                <p>
                    <input type="submit" value="Submit"/>
                </p>
            </fieldset>
        </form>

    </body>
</html>

我的CSS文件:

@CHARSET "ISO-8859-1";

.campo
{
    background-color: gray;
    border: 2px solid red;
}

.campo-invalido
{
    background-color : #ff0000;
    border: 1px solid #800000;
    width: 230px;
    color: white;
}

p
{
    color: blue;
    font-size: 22pt;
}

发生的情况是该样式没有被应用。在服务器端发现错误,但是当页面返回时,就好像 th: errorclass 属性不存在一样。我不知道我做错了什么。

我知道我的 css 文件正在被读取,因为 P 标签正在被风格化。

我正在使用:

  • Eclipse Mars.2 版本 (4.5.2)
  • thymeleaf 3.0.3 发布
  • thymeleaf-spring4 3.0.3 发布
  • spring-webmvc 4.1.1 发布
  • spring-context 4.1.1 发布
  • validation-api 1.1.0 最终版
  • hibernate-validator 5.3.4 最终版

如果有人想查看我项目的更多代码,我很乐意在这里展示。

感谢您的时间和耐心。

编辑

我也差点忘记了一些重要的事情,我的 Spring MVC 应用程序上下文文件:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd ">

    <!-- ################################################################################### -->
    <!-- MAPEAMENTO DE RECURSOS -->
    <!-- ################################################################################### -->

    <!-- Mapeamento de recursos (arquivos css, fontes, imagens, dentre outros). -->
    <mvc:resources mapping="/css/**" location="/WEB-INF/recursos/css/" />
    <mvc:resources mapping="/imagens/**" location="/WEB-INF/recursos/imagens/" />
    <mvc:resources mapping="/fontes/**" location="/WEB-INF/recursos/fontes/" />

    <!-- ################################################################################### -->
    <!-- ANOTAÇÕES E RECURSOS SPRING -->
    <!-- ################################################################################### -->

    <!-- Possibilita o uso de anotações Spring Mvc. -->
    <mvc:annotation-driven />

    <!-- Define local para procura de componentes Spring (beans configurados 
        por anotações em classes). -->
    <context:component-scan base-package="com.regra7.st.controle" />

    <!-- ################################################################################### -->
    <!-- INTERNACIONALIZAÇÃO -->
    <!-- ################################################################################### -->



    <!-- ################################################################################### -->
    <!-- CONFIGURAÇÕES DO THYMELEAF -->
    <!-- ################################################################################### -->

    <!-- Template Resolver para Template Engine. -->
    <!-- <bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver"> 
        <property name="prefix" value="/WEB-INF/templates/" /> <property name="suffix" 
        value=".html" /> <property name="templateMode" value="HTML5" /> </bean> -->

    <!-- SpringResourceTemplateResolver automatically integrates with Spring's 
        own -->
    <!-- resource resolution infrastructure, which is highly recommended. -->
    <bean id="templateResolver"
        class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver">
        <property name="prefix" value="/WEB-INF/templates/" />
        <property name="suffix" value=".html" />
        <!-- HTML is the default value, added here for the sake of clarity. -->
        <property name="templateMode" value="HTML" />
        <!-- Template cache is true by default. Set to false if you want -->
        <!-- templates to be automatically updated when modified. -->
        <property name="cacheable" value="true" />
    </bean>

    <!-- SpringTemplateEngine automatically applies SpringStandardDialect and -->
    <!-- enables Spring's own MessageSource message resolution mechanisms. -->
    <bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
        <property name="templateResolver" ref="templateResolver" />
        <!-- Enabling the SpringEL compiler with Spring 4.2.4 or newer can speed 
            up -->
        <!-- execution in most scenarios, but might be incompatible with specific -->
        <!-- cases when expressions in one template are reused across different 
            data -->
        <!-- ypes, so this flag is "false" by default for safer backwards -->
        <!-- compatibility. -->
        <property name="enableSpringELCompiler" value="true" />
    </bean>

    <!-- ################################################################################### -->
    <!-- CONFIGURAÇÕES DO SPRING MVC -->
    <!-- ################################################################################### -->

    <!-- View resolver do Thymeleaf. -->
    <bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
        <property name="templateEngine" ref="templateEngine" />
    </bean>

    <!-- Definição de HandlerMapping. -->
    <!-- Cuida de classes controladoras. -->
    <!-- <bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> 
        </bean> -->

    <!-- ################################################################################### -->
    <!-- INTERCEPTADORES -->
    <!-- ################################################################################### -->

    <!-- INTERCEPTADORES -->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/usuario/*" />
            <bean class="com.regra7.st.interceptadores.Login" />
        </mvc:interceptor>
    </mvc:interceptors>

</beans>

编辑2

在对验证代码进行了一些修改之后,我改变了使用的方法,突然间,事情开始起作用了。

以前,我使用 Bean 验证和我自己的注释来进行数据验证。我决定更改为使用 Spring 进行的验证,使用 org.springframework.validation.Validator,神奇的是一切都很顺利。

但是,我不想使用 Spring 的数据验证方法,而是使用 bean 验证注释。我已经知道我错在哪里了,但我不明白为什么。

我将输入我的登录验证代码:

// My bean validation annotation.
@Documented
@Constraint(validatedBy = Val_Login.class)
@Target({ElementType.METHOD , ElementType.FIELD , ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Login 
{
    String message() default "{com.regra7.st.login}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};

    int min() default 10;
    int max() default 20;
}

// Validator implementation.
public class Val_Login implements ConstraintValidator<Login , String>
{
    private int min;
    // private int max;

    @Override
    public void initialize(Login login)
    {
        this.min = login.min();
        // this.max = login.max();
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) 
    {
        return Util_Validador.isLoginValido(value , this.min);
    }
}

// The form input object.
public class For_Login
{
    @Login(min = 8)
    private String login;

    // Many things ommited
}

Util_Validador 类能够返回 true 或 false 值,这已经经过测试。如果我这样做:

import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

import com.regra7.st.formularios.For_Login;
import com.regra7.st.util.Util_Texto;

public class ValidadorFormulario implements Validator 
{
    @Override
    public boolean supports(Class<?> clazz) 
    {
        return For_Login.class.isAssignableFrom(clazz);
    }

    @Override
    public void validate(Object objeto, Errors erros) 
    {
        For_Login log = (For_Login) objeto;

        if(Util_Texto.isVazia(log.getLogin()) ||
            log.getLogin().length() < 8)
        {
            erros.rejectValue("login", "Login errado!");
        }
        if(Util_Texto.isVazia(log.getSenha()) ||
            log.getSenha().length() < 14)
        {
            erros.rejectValue("senha", "Senha errada!");
        }
    }
}

一切顺利。你们能帮我一点忙吗?我认为这可以帮助很多和我有同样处境的人。

一如既往,谢谢。

最佳答案

我做错了两件事:

  • 我忘记导入一些libraries needed by Hibernate Validator .
  • 我在表单字段中使用了前缀 (For_Login)。数据绑定(bind) 没有正常发生。事实上,是的,但 Thymeleaf 不是 正确认识它。拥有名为 _myField 的字段是没有用的 (例如),并设置 setMyField 和 getMyField 方法。任何一个 您使用名称 myField 编写字段,或者使用 名称 get_myField 和 set_myField。

关于java - 使用 Thymeleaf 3.x 处理表单验证 - 样式化错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41556490/

相关文章:

java - 在 x 个案例中执行最少 n% 的功能

java - Spring webflux,mongodb : Document is not saved into database

spring - createIndex = true不会在Elasticsearch中创建索引映射

java - spring mvc 将路径和所有子级重定向到另一个域

javascript - 如果用户在 jsp 中填写一个字段(同时使用 spring mvc 和 hibernate),我如何自动填写其他表单字段

java - Eclipse F3 快捷键回溯

java - 按质数创建 boolean 数组

java - 我不知道如何使用 while 循环来确保只有正确的名称才能跳出 while 循环

Spring security与Hibernate,存储加密密码

java - Bean创建异常: Error creating bean with name 'userController' : Injection of autowired dependencies failed