【问题标题】:Handling form validation with Thymeleaf 3.x - Stylizing errors使用 Thymeleaf 3.x 处理表单验证 - 样式化错误
【发布时间】:2017-01-09 20:35:55
【问题描述】:

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

这是我的控制器

@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();
}

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

<!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)
  • 百里香叶 3.0.3 发布
  • thymeleaf-spring4 3.0.3 发布
  • spring-webmvc 4.1.1 发布
  • spring-context 4.1.1 发布
  • validation-api 1.1.0 最终版
  • 休眠验证器 5.3.4 最终版

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

感谢您的时间和耐心。

编辑

我也差点忘记了一些重要的东西,我的 Spring MVC Application Context 文件:

<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 类能够返回真或假值,这已经过测试。如果我这样做:

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!");
        }
    }
}

一切顺利。请你们帮帮我好吗?我认为这可以帮助许多与我处于同一位置的人。

一如既往,谢谢。

【问题讨论】:

  • 尝试返回一个 ModelAnd 视图,作为 return new ModelAndView(Util_Paginas.PAG_LOGIN.toString(), "login", form);相应地更改您的方法签名
  • @lane.maxwell。你好!感谢您的评论!所以……我试着照你说的做,但不幸的是结果是一样的。
  • @lane.maxwell 嘿!我得到了更多信息。如果你不介意,有时间的话,可以看看吗?如果你没有办法帮助我,如果你能把我的问题告诉你的某个朋友,会不会问很多?我知道我很烦人,我很抱歉...随意做任何你想做的事。谢谢你。真的谢谢你。

标签: java spring spring-mvc web-applications thymeleaf


【解决方案1】:

我做错了两件事:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-22
    • 2018-09-19
    • 1970-01-01
    • 1970-01-01
    • 2020-01-30
    • 1970-01-01
    • 2011-08-27
    • 2020-06-09
    相关资源
    最近更新 更多