【发布时间】: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