Spring表单提交时触发Cannot invoke Integer.intValue()空指针异常求助
问题排查与解决方案
错误原因分析
报错Cannot invoke "java.lang.Integer.intValue()" because the return value of "java.util.List.get(int)" is null的核心原因有两个:
- 表单绑定逻辑缺陷:当前Thymeleaf表单中所有位置输入框共用同一个
positionsPoste名称,Spring MVC绑定List时,会将所有输入框的值(包括未填写的)存入List,未填写的位置会被设为null;同时未选中的复选框不会被加入etapes列表,导致etapes和positionsPoste的元素数量不匹配,或positionsPoste中存在null元素。 - 业务循环逻辑错误:双重循环会将每个选中的步骤与所有位置进行笛卡尔积配对,完全不符合“选中步骤对应单个位置”的需求,同时当
positionsPoste中存在null时,调用get(y)获取到null后,后续赋值会触发空指针。
修正步骤
1. 修正Thymeleaf表单绑定
为每个输入框添加索引绑定,确保选中的步骤和对应的位置一一对应:
<th:block th:each="etape, stat : ${etapes}"> <input class="form-label mt-4" type="checkbox" th:field="*{etapes}" th:value="${etape.id}"/> <label th:text="${etape.poste.name}"></label> <input class="form-label mt-4" type="number" th:field="*{positionsPoste[__${stat.index}__]}" th:placeholder="#{new.cheminementEtape.positionPoste.label}" th:disabled="${!#fields.get('etapes').contains(etape)}"/> <br> </th:block>
- 新增
stat变量获取遍历索引,绑定positionsPoste[索引]确保每个位置输入框对应List的指定位置 - 添加
th:disabled,当复选框未选中时禁用位置输入框,避免无效输入提交
2. 修正Service层循环逻辑
将双重循环改为单循环,实现选中步骤与对应位置的一对一绑定,并添加空值与越界校验:
List<CheminementEtape> cheminementEtapes = new ArrayList<>(); List<Etape> selectedEtapes = cheminementForm.getEtapes(); List<Integer> positions = cheminementForm.getPositionsPoste(); for (int i = 0; i < selectedEtapes.size(); i++) { if (i >= positions.size()) { break; // 避免索引越界 } Integer position = positions.get(i); if (position == null) { continue; // 跳过空的位置值 } CheminementEtape cheminementEtape = CheminementEtape.builder() .disable(false) .etape(selectedEtapes.get(i)) .cheminement(cheminement) .positionPoste(position) .build(); cheminementEtapes.add(cheminementEtape); } this.cheminementEtapeService.add(cheminementEtapes); return cheminement;
3. 优化表单实体类校验
为positionsPoste添加元素非空校验,提前拦截无效输入:
@Data public class CheminementForm { @NotNull(message = "{cheminement.form.name.notEmpty}") @Size(min=2, max=30) private String name; @NotNull(message = "{cheminementEtape.form.etape.notEmpty}") private List<Etape> etapes; @NotNull(message = "{cheminementEtape.form.positionPoste.notEmpty}") @NotEmpty(message = "{cheminementEtape.form.positionPoste.notEmpty}") @Valid private List<@NotNull(message = "{cheminementEtape.form.positionPoste.element.notEmpty}") Integer> positionsPoste; }
- 使用
@Valid和嵌套@NotNull校验,确保List中的每个位置值都不为空
内容的提问来源于stack exchange,提问作者user13906062
相关产品推荐
相关产品推荐

