0

Just got a strange behavior with validation of a very simple HTML form with Spring MVC and Thymleaf.

I have this methods for edit page rendering and submitted form handle.

    @GetMapping("/{id}")
    public String editPage(@PathVariable("id") Long id, Model model) {

        model.addAttribute("user", userService.findById(id)
                .orElseThrow(NotFoundException::new));
        return "user_form";
    }


    @PostMapping("/update")
    public String update(@Valid UserRepr user, BindingResult result, Model model) {
        logger.info("Update endpoint requested");

        if (result.hasErrors()) {
            return "user_form";
        }

        userService.save(user);
        return "redirect:/user";
    }

The wired thing in the update() method is that in case of a validation error the attribute of the model with form content has the name "userRepr" but not "user" as I expect and the thymleaf form view failed because of that.

It's easy to fix the problem by renaming the attribute but Is there some contract about such attribute naming? Is it changeable?

1 Answer 1

1

You can do this using @ModelAttribute.

@ModelAttribute is used to map/bind a a method parameter or method return type to a named model attribute. See @ModelAttributes JavaDoc. This is a Spring annotation.

@PostMapping("/update")
public String update(@Valid @ModelAttribute("user") UserRepr user, BindingResult result, Model model) {
    logger.info("Update endpoint requested");

    if (result.hasErrors()) {
        return "user_form";
    }

    userService.save(user);
    return "redirect:/user";
}

Why does it look like this?

Model object auto generates attribute names and then forward the above method calls to addAttribute(Object attributeValue).

Following are the rules of name generation strategy:

  • For an object which is not a collection, short class name is generated. For example for java.lang.String, 'string' will be generated.
  • For collections/arrays, 'List' is appended after the type of elements in it e.g. 'stringList'. The collection/array should not be empty because the logic uses the first element to find it's type.

You can check this link for more details. https://www.logicbig.com/tutorials/spring-framework/spring-web-mvc/spring-model-attribute-generated-names.html

Sign up to request clarification or add additional context in comments.

4 Comments

The problem is that the name of the model attribute in update() method is always 'userRepr'. No matter what the name of the attribute in editPage is.
I may have misunderstood, I added how this was changed as per your request. @AlexeyUsharovski
Thank you. And without ModelAttribute annotation Spring makes the attribute name based on the class name? Did you met something about that in documentation?
I added how the Model object works so you can understand why this is so. @AlexeyUsharovski

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.