ModelAttribute returns null values in controller i

2019-06-26 16:22发布

问题:

Ok, its time to seek help; I am 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?

回答1:

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



回答2:

Seems other fields aren't bound, try to bind for example product name

<td>${cartDetail.product.name}
<form:hidden path="cartDetails[${status.index}].product.name" value="${cartDetail.product.name}"/></td>


回答3:

I once spent a lot of time investigating a similar issue. Finally I found the culprit inside a Binder's initialization method:

@InitBinder
void initBinder(final WebDataBinder binder) {
    binder.setAllowedFields("name", ...);
}

This method sets a restriction on fields that are allowed for binding. And all the other fields are unbound, naturally resulting in null values.

The other possible reason: incorrect setters in a Bean annotated with @ModelAttribute. For example, Object setName(String name) instead of void setName(String).