Spring in Action第5版第3章问题:Taco对象ingredients字段为null
嘿,我之前学《Spring in Action(第5版)》的时候也踩过这个一模一样的坑!你的请求处理方法逻辑本身没毛病,问题大概率出在表单参数和Taco类属性的绑定环节,下面分几个关键点排查:
检查表单中食材选项的name属性
书中的设计页面是让用户多选食材,每个食材对应的复选框input标签的name必须是ingredients,这样Spring MVC才能把所有选中的食材值收集到Taco的ingredients集合里。正确的表单代码应该类似这样:<div th:each="ingredient : ${ingredients}"> <input type="checkbox" name="ingredients" th:value="${ingredient.id}"/> <span th:text="${ingredient.name}"></span> </div>如果你的表单里这个name写错了(比如写成
ingredient或者别的),Spring就找不到对应的属性来绑定,自然会让ingredients为null。确认Taco类的ingredients属性配置
虽然你说和书中一致,但还是再核对下:Taco类里的ingredients应该是集合类型(List<Ingredient>或Set<Ingredient>),并且要有对应的setter方法(或者用Lombok的@Data注解自动生成所有getter/setter)。示例代码如下:@Data public class Taco { private Long id; private String name; private List<Ingredient> ingredients; }要是没有setter方法,Spring MVC没法把表单提交的值注入到这个属性里。
检查是否配置了String到Ingredient的转换器
因为表单提交的是食材的id(字符串类型),而Taco的ingredients是Ingredient对象的集合,这时候需要一个Spring Converter来把字符串id转换成Ingredient实体。你需要创建这样的转换器并注册为组件:@Component public class IngredientConverter implements Converter<String, Ingredient> { private final IngredientRepository ingredientRepo; public IngredientConverter(IngredientRepository ingredientRepo) { this.ingredientRepo = ingredientRepo; } @Override public Ingredient convert(String ingredientId) { return ingredientRepo.findById(ingredientId).orElse(null); } }没有这个转换器的话,Spring没法把提交的字符串id转换成Ingredient对象,导致ingredients集合无法被填充,最终为null。
按照这几个步骤排查下来,应该就能解决你的问题啦!
内容的提问来源于stack exchange,提问作者Mandroid

