Search code examples
javaspring-mvcmodelattributespring-form

How to handle data from form in Spring MVC


I have jsp that show all posts in blog

<body>
    <table>
        <c:forEach var="post" items="${posts}">
            <tr>
                <td>${post.id}</td>
                <td>${post.text}</td>
                <td><a href="authors?name=${post.author}">Show author</a></td>
            </tr>
        </c:forEach>
    </table>

    <div>
        <a href="posts/get.json">JSON</a> <a href="posts/get.xml">XML</a>
    </div>

</body>

I have controller to handle it

@Controller
public class PostsController {

    @Autowired
    private PostDAO postDao;

    @RequestMapping("/posts")
    public String showAllPosts(ModelMap model) {

        List<Post> posts = postDao.findAll();
        model.addAttribute("posts", posts);
        return "posts";
    }

    @RequestMapping("/posts/get")
    public List<Post> getAllPosts() {
        List<Post> posts = postDao.findAll();
        return posts;
    }

}

Now I want to add form to save new post.

I add form in my jsp

<form:form method="POST" action="/posts/add" modelAttribute="post">
        <table>
            <tr>
                <td><form:label path="id">Id:</form:label></td>
                <td><form:input path="id" /></td>
            </tr>
            <tr>
                <td><form:label path="text">Text:</form:label></td>
                <td><form:input path="text" /></td>
            </tr>
        </table>
        <input type="submit" value="Save" />
    </form:form>

Also I add to controller.

@RequestMapping( value = "/posts/add", method = RequestMethod.POST)
    public String saveAdd(@ModelAttribute("post") Post post, ModelMap model) {

        model.addAttribute("posts", postDao.addPost(post));

        return "posts";
    }

Domain model Post.java

public class Post {

    private int id;

    private String author;

    private String text;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

}

But I get

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

Solution

  • Because your JSP contains the new form for adding a new post, it will need the model attribute post to be present when you go to /posts.

    @RequestMapping("/posts")
    public String showAllPosts(ModelMap model) {
    
        List<Post> posts = postDao.findAll();
        model.addAttribute("post", new Post()); // Add empty form backing object
        model.addAttribute("posts", posts);
        return "posts";
    }
    

    You could even split out model creation to a separate method if you find you're having to create the model in multiple places. This will ensure that its always available.

    @ModelAttribute("post")
    public Post createModel() {
        return new Post();
    }