Spring MVC表单提交时绑定ArrayList<CustomModel>至控制器失败
我来帮你解决这个Spring MVC集合绑定的问题——核心原因是你的表单字段命名不符合Spring用来识别集合元素的规则,所以没法自动映射到你的CustomPayCodesWrapper里。下面是具体的修复步骤:
1. 修正JSP表单的字段命名
Spring MVC要正确绑定ArrayList<CustomPayCodesModel>,需要使用带索引的字段名格式,比如customCodes[0].codeName、customCodes[0].codeValue,这样Spring才能识别出这是集合中对应索引位置的对象属性。
你原来的JSP里用${item.codeName}作为输入框的name属性,这完全不符合Spring的绑定规则。修改后的JSP代码如下(注意添加varStatus来获取循环索引):
<c:forEach var="item" items="${payCodes.customCodes}" varStatus="status"> <div class="row col-md-9"> <div class="form-group row"> <label for="payCodeName-${status.index}" class="col-md-2 col-form-label">Code Name</label> <div class="col-md-10"> <input type="text" class="form-control" id="payCodeName-${status.index}" name="customCodes[${status.index}].codeName" value="${item.codeName}"> </div> </div> <div class="form-group row"> <label for="payCodeValue-${status.index}" class="col-md-2 col-form-label">Code Value</label> <div class="col-md-10"> <input type="text" class="form-control" id="payCodeValue-${status.index}" name="customCodes[${status.index}].codeValue" value="${item.codeValue}"> </div> </div> </div> </c:forEach>
另外注意:原来的id="payCode"会在循环中重复,我改成了动态的id="payCodeName-${status.index}"和id="payCodeValue-${status.index}",避免DOM元素ID冲突。
2. 简化并修正控制器方法
你原来的控制器方法参数太冗余了,同时用了@ModelAttribute、ArrayList、@RequestBody等,这完全没必要。对于普通表单提交(application/x-www-form-urlencoded类型),只需要用@ModelAttribute来接收包装类即可,不需要@RequestBody(它是用来处理JSON/XML等请求体的)。
修改后的控制器代码:
@RequestMapping(value = "updateCustomPaymentCodes", method = RequestMethod.POST) public ModelAndView updateCustomPayCodes(ModelAndView modelAndView, @ModelAttribute("payCodes") CustomPayCodesWrapper payCodesWrapper) { // 直接获取绑定后的集合 List<CustomPayCodesModel> customCodes = payCodesWrapper.getCustomCodes(); // 这里添加你的业务处理逻辑,比如保存到数据库等 return showCustomPaymentCodes(modelAndView); }
3. 额外注意事项
- 确保
CustomPayCodesModel有默认无参构造函数:Java会在你没有显式定义构造函数时自动生成,所以你现在的代码没问题;如果之后添加了带参构造函数,一定要手动补上无参的。 - CSRF令牌处理:只要你开启了Spring Security的CSRF防护,并且表单里包含了Spring自动生成的CSRF隐藏字段(一般是
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>),Spring会自动处理CSRF验证,不会把CSRF值绑定到你的包装类里,解决了你之前的冗余值问题。 - 如果是AJAX提交:如果之后改成用AJAX提交JSON数据,那需要把请求头设为
Content-Type: application/json,然后用@RequestBody CustomPayCodesWrapper payCodesWrapper来接收,这时候前端要把数据整理成对应的JSON结构。
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

