13

How to pass thymeleaf(th:object) values to controller.

HTML:

<form id="searchPersonForm" action="#" th:object="${person}" method="post" >  
</form>

SearchPersonController:

@RequestMapping(value = "/modify/{pid}", method = RequestMethod.GET)
    public String modifyPersonData(Principal principal, @ModelAttribute("person") Person person, UserRoles userRoles, Model model, @PathVariable("pid") Long pid ) {
         //modify data
    }

I am trying to pass like @ModelAttribute("person") Person person but this is not retrieving form values from previous page.

Can anyone help on this.

Thanks.

Java_User
  • 475
  • 2
  • 11
  • 30

1 Answers1

16

Preferably use th:action as a form attribute instead of action, and specify the binding like the following:

<form th:action="@{/the-action-url}" method="post"
    th:object="${myEntity}">

    <div class="modal-body">
        <div class="form-group">
            <label for="name">Name</label> <input type="text"
                class="form-control" id="name" th:field="*{name}"> </input>
        </div>

        <div class="form-group">
            <label for="description">Description</label> <input type="text"
                class="form-control" id="description"
                th:field="*{description}"> </input>
        </div>
    </div>
</form>

I back this form with a Spring controller that initializes the model attribute (myEntity object in the form). This is the relevant part of the controller class:

@ModelAttribute(value = "myEntity")
public Entity newEntity()
{
    return new Entity();
}

The @ModelAttribute annotation ensures that the model object is initialized by Spring for every request.

Set a model named "command" during the first get request to your controller:

@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView getRanks(Model model, HttpServletRequest request)
{
    String view = "the-view-name";
    return new ModelAndView(view, "command", model);
}

And, to access the model as it results after the form submission, implement the relative method:

@RequestMapping(value = "/the-action-url", method = RequestMethod.POST)
public View action(Model model, @ModelAttribute("myEntity") Entity myEntity)
{
    // save the entity or do whatever you need

    return new RedirectView("/user/ranks");
}

Here, the parameter annotated with @ModelAttribute is automatically bound to the submitted object.

Evil Toad
  • 3,053
  • 2
  • 19
  • 28
  • Thankyou for the explanation. Can I ask few doubts. 1. I have currents 5 submit buttons in the current page(search page) like search, copy, view /modify ,.. So we don't have a default URL to specify for `th:action="@{/the-action-url}" ` . 2.Earlier I was using ` RequestMethod.POST` for `modifyPersonData` and I got `Person` form values from view by just using `Person person` without `@ModelAttribute("person")` . But when I changed to ` RequestMethod.GET`, I am not able to retrieve `Person ` values and I tried with `@ModelAttribute("person") Person person` and this is not working too. – Java_User Aug 18 '15 at 03:50
  • 1. You can use 5 forms (one for each button) with different action urls OR an additional parameter (e.g. a hidden field) and a bit of javascript to discriminate the button that's been pressed. 2.If you map the controller method to GET requests ( `@RequestMapping(value = "/modify/{pid}", method = RequestMethod.GET)` ), then it won't match with the form, that is set to use post. – Evil Toad Aug 18 '15 at 07:19
  • Thankyou EvilTodd. I want to map the controller to GET requests, so have to change form as get. But this is passing all input fields in the url. So I thought modelattribute can handle when the form is set to post and controller is get. – Java_User Aug 19 '15 at 05:38