Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

[Spring MVC - Thymeleaf]- Form validation and error messages

I´m trying to create a form and validate its data via @Valid on the command object. The validation performs well, but an error is ocurring going back to web.

This is what I have:

HTML

<div id="content" layout:fragment="contenido">
    <div sec:authorize="isAnonymous()">
        <form class="form-horizontal" action="#" th:action="@{register}" th:object="${userForm}" method="post">
            <input type="hidden" name="_csrf" th:value="${_csrf.token}"/>
            <fieldset>
                <label for="alias" th:text="#{form.register.alias}">Alias</label>
                <input id="alias" type="text" th:field="*{alias}" placeholder="Su alias" required="required" autofocus="autofocus"/>

                <label for="pass" th:text="#{form.register.password}">Contraseña</label>
                <input id="pass" type="password" th:field="*{password}" pattern="[\w\d-_]{5,15}" required="required" th:title="#{form.error.password}"/>
                <p th:if="${#fields.hasErrors('password')}" th:errors="*{password}">Error en el dato ingresado</p>

                <button type="submit" name="save" class="btn btn-primary" th:text="#{control.register}">Registrarme</button>
            </fieldset>
        </form>
    </div>
</div>

Controller

@RequestMapping(value = "/register", params = {"save"}, method = RequestMethod.POST) 
public String register (final ModelMap model, @Valid final UsuarioForm userForm, final BindingResult result) { 
    if (result.hasErrors()) { 
        return "register"; 
    } else { 
        return "redirect:/" + HomeController.PAGE_NAME; 
    } 
} 

When Clicking on "submit" the "register" method is called, result.hasErrors() is true so the same page should be displayed, but this error occurs.

Stack

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'userForm' available as request attribute 
        org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:144) 
        org.thymeleaf.spring4.util.FieldUtils.getBindStatusFromParsedExpression(FieldUtils.java:396) 
        org.thymeleaf.spring4.util.FieldUtils.getBindStatus(FieldUtils.java:323) 
        org.thymeleaf.spring4.util.FieldUtils.getBindStatus(FieldUtils.java:289) 
        org.thymeleaf.spring4.processor.attr.AbstractSpringFieldAttrProcessor.processAttribute(AbstractSpringFieldAttrProcessor.java:98) 
        org.thymeleaf.processor.attr.AbstractAttrProcessor.doProcess(AbstractAttrProcessor.java:87) 
        org.thymeleaf.processor.AbstractProcessor.process(AbstractProcessor.java:212) 
        org.thymeleaf.dom.Node.applyNextProcessor(Node.java:1017) 
        org.thymeleaf.dom.Node.processNode(Node.java:972) 

If I add "userForm" to the model in the Controller this way:

Controller Modified

@RequestMapping(value = "/register", params = {"save"}, method = RequestMethod.POST) 
public String register (final ModelMap model, @Valid final UsuarioForm userForm, final BindingResult result) { 
    if (result.hasErrors()) { 
        model.addAttribute("userForm", userForm); //THIS LINE IS ADDED 
        return "register"; 
    } else { 
        return "redirect:/" + HomeController.PAGE_NAME; 
    } 
} 

The error disappears, BUT... the expression in the HTML ${#fields.hasErrors('password')} results false, so I cant show the error messages to the user.

Any idea of why this behaviour is happening? Thanks in advance!

PS: I am using Spring MVC 4.1.2 with Thymeleaf 2.1.4

like image 300
Emiliano Schiano Avatar asked Dec 29 '14 13:12

Emiliano Schiano


People also ask

Is Thymeleaf supported by Spring MVC?

Thymeleaf offers a set of Spring integrations that allow you to use it as a fully-featured substitute for JSP in Spring MVC applications.

How do I add validation to Thymeleaf?

Click Dependencies and select Spring Web, Thymeleaf, and Validation. Click Generate. Download the resulting ZIP file, which is an archive of a web application that is configured with your choices.

How do I validate my email with Thymeleaf?

1 Answer. Show activity on this post. Use type="email" instead of text . Use required if you would like the input field as mandatory input.


1 Answers

This

public String register(final ModelMap model,
        @Valid final UsuarioForm userForm,
        final BindingResult result)

should be:

public String register(final ModelMap model,
        @ModelAttribute("userForm") @Valid final UsuarioForm userForm,
        final BindingResult result)

Notice the @ModelAttribute annotation.

like image 171
Bohuslav Burghardt Avatar answered Sep 21 '22 04:09

Bohuslav Burghardt