提前感谢您的帮助。
我的模型中有以下对象关联:
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)
....
自定义属性编辑器似乎正在执行其工作,并且没有传递空/空字符串。
如果表单和控制器在查看表单时进行转换,为什么在处理表单时遇到问题?我在这里缺少什么?
答案 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));
}
也许这会帮助别人。