Search code examples
javaspringvalidationspring-mvc

Spring validator annotation and error redirection


I m actually studying the Spring framework with Spring Boot and Sprint MVC. I m doing a form that post some data to complete an object, and I need to validate some values.

The fact is that the validation works, in fact, if I dont respect the validation, I m "redirected" (not really in fact, the URL doesn't change) to the error.html content.

How should I do to manage my redirection correctly ? This doesn't work this way :

@RequestMapping(value = "/print", method = RequestMethod.POST)
    public String printPost(@ModelAttribute("printerentity") @Valid PrinterEntity print, Model model, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return "redirect:/formPrinter";
        }

        model.addAttribute("printed", print.getName());
        model.addAttribute("printerentity", new PrinterEntity());

        return "index";
    }

And the form :

<form method="post" th:action="@{/print}" th:object="${printerentity}">
    <input type="text" th:field="*{name}"/>
    <button type="submit">Valider</button>

    <p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</p>
</form>

What am I doing wrong ?

EDIT : It seems that when I have an error, I dont pass in the controller code :o =>

 @RequestMapping(value = "/print", method = RequestMethod.POST)
    public String printPost(@ModelAttribute("printerentity") @Valid PrinterEntity print, Model model, BindingResult bindingResult) {
        System.out.println("I dont passe here when error but I m redirected");
        if (bindingResult.hasErrors()) {
            return "formPrinter";
        }

        model.addAttribute("printed", print.getName());
        model.addAttribute("printerentity", new PrinterEntity());

        return "index";
    }

thanks for advance


Solution

  • How should I do to manage my redirection correctly ?

    When you redirect a request, then the current request destroyed, and a new request object is created to process the request, so as per Sotirios Delimanolis has mentioned in comment, that model attributes are request attributes, which are available for per request only, If you want to store model attributes in the HTTP session between requests use @SessionAttributes, or a FlashAttributes.

    As per your html form you have:

    <p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</p>
    

    you mean you want to show validation errors in the same page, then don't redirect return the same view.

    if (bindingResult.hasErrors()) {
        //return "redirect:/formPrinter";
        return "your html form view";
    }
    

    then, on your view you can render all validation error messages like:

    <p th:each="err : ${#fields.errors('*')}" th:text="${err}"></p>