Spring MVC@modelAttribute如何发送对象列表以单独的形式查看并一次更新一个对象



我有一个控制器,它可以进入数据库并获取书籍列表。我喜欢使用@modelAttribute以单独的形式显示各个书籍,这样我就可以对每个项目进行快速编辑。

控制器

@RequestMapping("/")
public String pagIndex(Model model){
    System.out.println("loading index page");
    // Get list of books
    List<Book> books = bookDao.getBookList();
    // List of object to Model
    model.addAttribute("books", books);
    return "index";
}

查看

<h3>Book Inventory</h3>
<table>
    <tr>
        <td>ID</td>
        <td>Book Name</td>
        <td>ISPN</td>
        <td>Price</td>
        <td></br><td>
        <td>Object</td>
    </tr>
    <!-- Each book in separate form for easy update -->
    <c:forEach var="book" items="${books}">
    <tr>
        <sf:form class="editeForm" action="${pageContext.request.contextPath}/edititem" modelAttribute="book"  method="POST">
            <td>${book.id} <input type="hidden" path="id" name="id"></td>
            <td><sf:input type="text" path="name" name="name" /></td>
            <td><sf:input type="text" path="ispn" name="ispn" /></td>
            <td><sf:input type="text" path="price" name="price" /></td>
            <td></br><td>
            <td>${book}</td>
            <td><input type="submit" value="save edite"><input type="submit" name="delete" value="delete"></td>
        </sf:form>
    </tr>
    </c:forEach>
</table>

当我设置modelAttribute="book"堆栈跟踪为时

Caused by: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'book' available as request attribute
at org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:144)

modelAttribute="${book}"堆栈跟踪是

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'Book bean [id=1, name=Java: A Beginner's Guide, ispn=978-0071809252, price=18' available as request attribute

更新:如果我使用普通的JSTL,它是有效的,但无论如何都要使用modelAttriburte?

<h3>Book Inventory</h3>
<table>
    <tr>
        <td>ID</td>
        <td>Book Name</td>
        <td>ISPN</td>
        <td>Price</td>
        <td></br><td>
        <td>Object</td>
    </tr>
    <!-- Each book in separate form for easy update -->
    <c:forEach var="book" items="${books}">
    <tr>
        <form class="editeForm" action="${pageContext.request.contextPath}/edititem"  method="POST">
            <td>${book.id} <input type="hidden" name="id" value="${book.id}"/></td>
            <td><input type="text" name="name" value="${book.name} /></td>
            <td><input type="text" name="ispn" value="${book.ispn} /></td>
            <td><input type="text" name="price" value="${book.price} /></td>
            <td></br><td>
            <td>${book}</td>
            <td><input type="submit" value="save edite"><input type="submit" name="delete" value="delete"></td>
        </form>
    </tr>
    </c:forEach>
</table>

编写时:

<c:forEach var="book" items="${books}">

book变量确实是为每次迭代创建的,但它只是一个页面范围的变量,而不是请求属性。正如错误所说,Spring modelAttribute应该是请求属性。由于我不知道如何动态地使book变量成为真正的spring模型属性,所以我的建议是坚持使用普通的JSTL。

由于JSTLView默认情况下只将模型属性作为带有名称的请求属性,因此可以使用一个小scriptlet来欺骗spring:

<c:forEach var="book" items="${books}">
    <%
        Object obj = pageContext.findAttribute("book");
        request.setAttribute("book", obj);
    %>
    ...

但我真的强烈建议您不要这样做,因为它依赖于Spring实现细节,即使在小版本

中也可能发生更改

使用<c:forEach var="result" items="${books}" varStatus="status">${result.id}。你有机会登记管制员吗?你的书。

最新更新