0

Thanks in advance for any help.

I have the following object association in my model:

public class Contract {
   private Integer id;
   private String name;
   //getters/setters...
}

public class User {
   ....
   private List<Contract> contracts;
   ....
}

Controller:

@RequestMapping(....)
public String getUser(@PathVariable Integer userId, Model model) {
   ....
   model.addAttribute(userDao.findUser(userId));
   model.addAttribute("contractsList", contractDao.findAllContracts());
   ....
}

@RequestMapping(....)
public String processUser(@ModelAttribute User user, Model model) {
   ....

   //Create a copy of the user to update...
   User userToUpdate = userDao.findUser(user.getId);

   ....
   userToUpdate.setContracts(user.getContracts());
   //set other properties...

   userDao.updateUser(userToUpdate);

   return "someSuccessView";
} 

@InitBinder
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
   binder.registerCustomEditor(Contract.class, new UserContractsPropertyEditor());
}

My PropertyEditor:

public class UserContractsPropertyEditor extends PropertyEditorSupport {

   @Inject ContractDao contractDao;

   @Override
   public void setAsText(String text) throws IllegalArgumentException {
      System.out.println("matching value: " + text);
      if (text != "") {
         Integer contractId = new Integer(text);
         super.setValue(contractDao.findContract(contractId));
      } 
   }

}

My JSP form:

<form:form commandName="user"> 
   <%-- Other fields... --%>
   <form:checkboxes items="${contractsList}" 
      path="contracts" 
      itemValue="id" 
      itemLabel="name" />   
</form:form>

The form renders correctly. That is, the checkbox list of Contracts is generated and the correct ones are "checked." The problem is when I submit I get:

java.lang.IllegalArgumentException: 'items' must not be null
    at org.springframework.util.Assert.notNull(Assert.java:112)
    at org.springframework.web.servlet.tags.form.AbstractMultiCheckedElementTag.setItems(AbstractMultiCheckedElementTag.java:83)
    at org.apache.jsp.WEB_002dINF.jsp._005fn.forms.user_jsp._jspx_meth_form_005fcheckboxes_005f0(user_jsp.java:1192)
    ....

The custom property editor seems to be doing its job and there are no null/empty strings being passed.

If the form and controller makes the conversion when viewing the form, why is it having trouble when processing the form? What am I missing here?

2 Answers 2

2

You need to ensure that a call to getContract() returns a List instance:

public List<Contract> getContracts() {
    if (contracts == null) contracts = new ArrayList<Contract>();
    return contracts;
}
Sign up to request clarification or add additional context in comments.

Comments

0

Thanks for your response. I guess a fresh set of eyes first thing in the morning does the trick again.

Apparently, my custom property editor had no clue what to do with the id value I was passing in since it couldn't access my DAO/service. So, I had to change the constructor:

public class UserContractsPropertyEditor extends PropertyEditorSupport {

   private ContractDao contractDao;

   public UserContractsPropertyEditor(ContractDao contractDao) {
      this.contractDao = contractDao;
   }

   @Override
   public void setAsText(String text) throws IllegalArgumentException {
      Integer contractId = new Integer(text);
      Contract contract = contractDao.findContract(contractId);
      super.setValue(contract);
   }

}

Then, modified the initBinder in my controller:

   @Inject ContractDao contractDao;
   ....    
   @InitBinder
    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
       binder.registerCustomEditor(Contract.class, new UserContractsPropertyEditor(this.contractDao));
    }

Maybe this will help someone else.

1 Comment

In case you are still active: I pretty much copied your (corrected) example and getting error 400. What is wrong?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.