弹簧列表绑定

时间:2012-04-03 16:37:37

标签: forms spring list

提前感谢您的帮助。

我的模型中有以下对象关联:

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

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

控制器:

@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());
}

我的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));
      } 
   }

}

我的JSP表单:

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

表单呈现正确。也就是说,生成合同的复选框列表,并“检查”正确的合同。问题是,当我提交时,我得到:

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)
    ....

自定义属性编辑器似乎正在执行其工作,并且没有传递空/空字符串。

如果表单和控制器在查看表单时进行转换,为什么在处理表单时遇到问题?我在这里缺少什么?

2 个答案:

答案 0 :(得分:2)

您需要确保对getContract()的调用返回List实例:

public List<Contract> getContracts() {
    if (contracts == null) contracts = new ArrayList<Contract>();
    return contracts;
}

答案 1 :(得分:0)

感谢您的回复。我想早上第一件事情就是新鲜的眼睛再次成功。

显然,我的自定义属性编辑器不知道如何处理我传入的id值,因为它无法访问我的DAO /服务。所以,我不得不改变构造函数:

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);
   }

}

然后,在我的控制器中修改了initBinder:

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

也许这会帮助别人。