javaspringspring-mvcbindingmodelattribute

ModelAttribute returns null values to controller in Spring MVC


I'm sending a (shopping) Cart ModelAttribute to my JSP, allowing the user to edit the quantity, when the Model is POST to the controller, the fields are null except the editable (quantity) field. I have researched for days on similar issues, but nothing is matching. I am using Spring 3.1.

Here is my controller on the GET and POST:

@Controller
public class CartController {

      @Autowired
      private Cart cart;        

      @RequestMapping(value = "/cart", method = RequestMethod.GET)  
      public String showCart(Model model) {
         logger.debug("CartController.showCart() Cart: {}", this.cart);
         model.addAttribute(cart);
         return "cart/cart";
      }

and POST:

   @RequestMapping(value = "/cart", method = RequestMethod.POST, params = "update")
   public String update(@ModelAttribute("cart") Cart cart, BindingResult result, Model model) {
      logger.debug("CartController.update() Cart: {}", cart); 
      return "cart/cart";
   }

My JSP:

<div class="container MainContent">
   <form:form method="POST" modelAttribute="cart">
      <fieldset>
         <legend>Cart</legend>
         <table class="table">
            <thead>
               <tr>
                  <th>Product Name</th>
                  <th>Quantity</th>
                  <th>Product Price</th>
               </tr>
            </thead>
            <tbody>
               <c:forEach items="${cart.cartDetails}" var="cartDetail" varStatus="status">
                  <tr>
                     <td>${cartDetail.product.name}</td>                     
                     <td><form:input path="cartDetails[${status.index}].quantity" size="1" /></td>                     
                     <td>${cartDetail.price}</td>
               </c:forEach>
               <tr>
                  <b><td colspan="2" align="right"><spring:message code="order.total" /></b>
                  </td>
                  <td>${cart.totalCartPrice}</td>
               </tr>
            </tbody>
         </table>
      </fieldset>
      <div></div>
      <button id="order" name="order">
         <spring:message code="button.order" />
      </button>
      <button id="update" name="update">
         <spring:message code="button.update" />
      </button>
   </form:form>
</div>

and the log results for cart before on GET:

CartController.showCart() Cart: Cart [cartDetails=[CartDetail product=com.Product@c26440[name=My Name], quantity=1]], totalCartPrice=10.00]

and after updating the quantity from 1 to 3 in the JSP, and then POST to the controller:

CartController.update() Cart: Cart [cartDetails=[CartDetail [product=null, quantity=3]], totalCartPrice=null]

I've read several similar post here, and on the Spring forum, and tried different suggested solutions with no luck. It seems like my edited quantity results are getting bound to the Object correctly, but why aren’t the others?


Solution

  • Assuming you have all the necessary fields in your Form object;

    You have to specify the form fields and fill the value with your data.

    <td>${cartDetail.product.name}</td> 
    

    will only print the result to the screen. If you want to bind it to your form you have to put it in a spring form input such as:

    <form:input path="productName"  value="${cartDetail.product.name}"/> 
    

    If you don't want it to be editable then you can put it into a hidden field but in the end you'll have to put it in a form element in the jsp and have a corresponding field in your form POJO