Mike3355
Mike3355

Reputation: 12081

Thymeleaf Neither BindingResult nor plain target object for bean name 'person' available as request attribute

From what I can tell this is set up correctly but I am getting the following error:

java.lang.IllegalStateException: Neither BindingResult nor plain target 
object for bean name 'person' available as request attribute

Form

<form action="#" th:action="@{/person}" th:object="${person}" method="post" th:required="required">
    <input type="text" th:field="*{subject}" class="contact col-md-6" placeholder="Name *" th:required="required"/>
    <input type="text" th:field="*{name}" class="contact col-md-6" placeholder="Name *" th:required="required"/>
    <input type="text" th:field="*{lastName}" class="contact col-md-6" placeholder="Name *" th:required="required"/>
    <input type="email" th:field="*{email}" class="contact noMarr col-md-6" placeholder="E-mail address *" th:required="required"/>
    <textarea name="comment" class="contact col-md-12" th:field="*{message}" placeholder="Message *"></textarea>
    <input type="submit" id="submit" class="contact submit" value="Send message"/>
</form>

Person.java

public class Person {

    private int id;
    private String name;
    private String lastName;
    private String email;
    private String subject;
    private String message;

    ....
}

Controller

@Controller
public class ApplicationController {

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String indexPage() {
        return "index";
    }

    @RequestMapping(value="/person", method=RequestMethod.GET)
    public String contactForm(Model model) {
        model.addAttribute("person", new Person());
        return "index";
    }

    @RequestMapping(value="/person", method=RequestMethod.POST)
    public String contactSubmit(@ModelAttribute Person person, Model model) {
        model.addAttribute("person", person);
        return "result";
    }
}

I looked at Spring-boot and Thmeleaf setup and it looks like my setup is identical.

--------------------- Update 1 -----------------------

I have changed my post method to include BindingResult with no success.

@RequestMapping(value="/person", method=RequestMethod.POST)
public String contactSubmit(@Valid @ModelAttribute Person person, BindingResult bindingResult, Model model) {

    if(bindingResult.hasErrors()){
        System.out.println("There was a error "+bindingResult);
        System.out.println("Person is: "+ person.getEmail());
        return "index";
    }

    model.addAttribute("person", person);
    return "result";
}

Upvotes: 13

Views: 25950

Answers (4)

Manuel CCH
Manuel CCH

Reputation: 11

You need declare a @ModelAttribute for "person". Something like:

@ModelAttribute("Myperson")
public Person newPerson() {
    return new Person();
}

Then, declare you @PostMapping and set in @ModelAttribute the name "person".

@RequestMapping(value="/person", method=RequestMethod.POST)
public String contactSubmit(@ModelAttribute Person person, Model model) {
    model.addAttribute("person", person);
    return "result";
}

I hope it works for whoever reads this :)

Upvotes: 1

Vaishali Wadkar
Vaishali Wadkar

Reputation: 71

Model attribute has to be initialized (using GET method) before calling post method. In your case you need one more method in controller which does model.addAttribute("person",new Person()); and it has to be called before post.

Refer below link: https://spring.io/guides/gs/handling-form-submission/ OR http://forum.thymeleaf.org/Neither-BindingResult-nor-plain-target-object-for-bean-name-miniDoniie-available-as-request-attribute-td4027859.html

It has GetMapping as well as PostMapping in controller.

Upvotes: 7

Mike3355
Mike3355

Reputation: 12081

First I had the form in index.html

 @RequestMapping(value = "/", method = RequestMethod.GET)
    public String indexPage(){
        return "index";
    }

So when my form:

<form th:action="@{/person}" th:object="${person}" method="post" >
                <input type="text" th:field="*{subject}" class="contact col-md-6" placeholder="Subject *" />
                <input type="text" th:field="*{name}" class="contact col-md-6" placeholder="Name *" />
                <input type="text" th:field="*{lastName}" class="contact col-md-6" placeholder="Last Name *" />
                <input type="email" th:field="*{email}" class="contact noMarr col-md-6" placeholder="E-mail address *" />
                <textarea name="comment" class="contact col-md-12" th:field="*{message}" placeholder="Message *" ></textarea>
                <input type="submit" id="submit" class="contact submit" value="Submit" />
                <input type="reset" value="Reset" />
            </form>

Was looking for / it was hitting the above method, NOT:

@RequestMapping(value="/", method=RequestMethod.GET)
    public String contactForm(@Valid @ModelAttribute("person") Person person, BindingResult bindingResult,
                              HttpServletRequest request, Model model) throws IOException {

        if(bindingResult.hasErrors()){
            System.out.println("There was a error "+bindingResult);

            return "index";
        }

        model.addAttribute("person", new Person());
        return "index";
    }

Which was correct!

I had to remove the first method and it worked.

Upvotes: 0

sanluck
sanluck

Reputation: 1554

You forgot to add BindingResult after your @ModelAttribute :

@RequestMapping(value="/person", method=RequestMethod.POST)
public String contactSubmit(@ModelAttribute Person person, BindingResult bindingResult, Model model) {
    if (bindingResult.hasErrors()) {
        //errors processing
    }  
    model.addAttribute("person", person);
    return "result";
}

I'm already have answered to question like this :

Upvotes: 7

Related Questions