Spring MVC @ModelAttribute does not contain submitted form results

I have a problem processing a form using Thymeleaf and Spring-MVC. It's my opinion:

<html xmlns:th="http://www.thymeleaf.org">
    <head>
    </head>
    <body>
        <div class="container" id="containerFragment" th:fragment="containerFragment">
            <form
                action="#"
                th:action="@{/search}"
                th:object="${searchInfo}"
                method="post" >
                <fieldset id="search-query">
                    <input
                        type="text"
                        name="search"
                        value=""
                        id="search"
                        placeholder="Search for user"
                        required="required"
                        th:value="*{searchQuery}" />
                    <input
                        type="submit"
                        value="Search"
                        name="submit"
                        class="submit"/>
                </fieldset>
            </form>
        </div>
    </body>
</html>

      

this is my controller:

/** Search form */
@RequestMapping(value = "/search", method = RequestMethod.GET)
public String search(Model model) {
    model.addAttribute("searchInfo", new SearchForm());
    return "search";
}

/** Search form */
@RequestMapping(value = "/search", method = RequestMethod.POST)
public ModelAndView search(BindingResult result,
        @Valid @ModelAttribute("searchInfo") SearchForm searchForm) {

    String login = searchForm.getSearchQuery();
    User user = userService.findUserByLogin(login);

    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("search-results");
    modelAndView.addObject("user", user);

    return modelAndView;
}

      

and the search form:

public class SearchForm {

    String searchQuery;

    public String getSearchQuery() {
        return searchQuery;
    }

    public void setSearchQuery(String searchQuery) {
        this.searchQuery = searchQuery;
    }

    @Override
    public String toString() {
        return "SearchForm [searchQuery=" + searchQuery + "]";
    }
}

      

The problem is that the login at this point in the controller is null:

String login = searchForm.getSearchQuery();

      

It looks like a new SearchForm object created for the POST method, but there is already one that was created in the GET phase and should contain the search request. I don't understand this behavior.

+3


source to share


3 answers


Spring should map HTML form attributes to your model: SearchForm .

Spring MVC builds accordions with request parameters and your model object objects and sets the appropriate properties in your Object model before passing the object to your controller method.



You named the HTML property (and the name of the query parameter automatically) as id = "search". But SearchForm doesn't have that property. Instead, it has a searchQuery property. So after Spring MVC failed to set the searchQuery value to your SearchForm, it passes the model with a null attribute.

+3


source


Change th: value = "{searchQuery}" to th: field = "{searchQuery}".



I hope this works.

0


source


This worked for me:

FormTestController.java

@Controller
public class FormTestController {

    @RequestMapping(value = "/form-test-1.jhtml", method = RequestMethod.GET)
    public String formTest1(@ModelAttribute("form1") Form1TestVO form1TestVO, Model model){
        System.out.println("You've submited: " + form1TestVO.getName())
        model.addAttribute("form1", new Form1TestVO("Form 1 test"));
        return "form-test-1";
    }

}

      

form test-1.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.thymeleaf.org" >
<head>
    <title>Form test 1</title>
</head>
<body >

    <form th:object="${form1}" th:action="@{/form-test-1.jhtml}" >
        <input  th:field="*{name}" />
        <button>Send</button>
    </form>

</body>
</html>

      

Form1TestVO

public class Form1TestVO {
    private String name;

    public Form1TestVO() {
    }

    public Form1TestVO(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

      

Link

0


source







All Articles