【发布时间】:2021-04-12 13:27:08
【问题描述】:
我是 Spring 新手,正在阅读“Spring in Action”(这确实是一本好书)。 在这里,我在本书的一个例子中遇到了一个让我很困惑的问题。 在这个example中,有两个控制器分别对应两个路径。一个是 DesignTacoController,另一个是 OrderController。
在我自己试验这个例子的过程中,我首先复制了 OrderController,它是一个非常简单的类,如下所示。当网页上有is/isn't错误输入时,这段代码可以完美运行。
@Slf4j
@Controller
@RequestMapping("/orders")
public class OrderController {
@GetMapping("/current")
public String orderForm(Model model) {
model.addAttribute("order", new Order());
return "orderForm";
}
@PostMapping
public String processOrder(@Valid Order order, Errors errors) {
if (errors.hasErrors()) {
return "orderForm";
}
log.info("Order submitted: " + order);
return "redirect:/";
}
}
然后我按照上面的OrderController自己实现了DesignTacoController
@Slf4j
@Controller
@RequestMapping("/design")
public class DesignTacoController {
@GetMapping
public String showDesignForm(Model model) {
List<Ingredient> ingredients = Arrays.asList(
// adding some ingredients
);
Type[] types = Ingredient.Type.values();
for (Type type: types) {
model.addAttribute(
type.toString().toLowerCase(Locale.ROOT),
filterByType(ingredients, type));
}
model.addAttribute("design", new Taco());
return "design";
}
@PostMapping
public String processDesign(@Valid Taco design, Errors errors) {
if (errors.hasErrors()) {
return "design";
}
log.info("Processing design: " + design);
return "redirect:/orders/current";
}
// more methods ignored
}
使用此实现,当没有错误输入时它可以正常工作。但是,如果我对验证器输入一些内容,我会得到一个
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'design' available as request attribute
通过在stackoverflow(this question)上搜索并检查github上的original example code,我发现这个类应该这样实现
@Slf4j
@Controller
@RequestMapping("/design")
public class DesignTacoController {
@ModelAttribute
public void addIngredientsToModel(Model model) {
List<Ingredient> ingredients = Arrays.asList(
// adding some ingredients
);
Type[] types = Ingredient.Type.values();
for (Type type : types) {
model.addAttribute(type.toString().toLowerCase(),
filterByType(ingredients, type));
}
}
@GetMapping
public String showDesignForm(Model model) {
model.addAttribute("design", new Taco());
return "design";
}
@PostMapping
public String processDesign(@Valid @ModelAttribute("design") Taco design, Errors errors, Model model) {
if (errors.hasErrors()) {
return "design";
}
// Save the taco design...
// We'll do this in chapter 3
log.info("Processing design: " + design);
return "redirect:/orders/current";
}
// more methods ignored
}
我的问题来了,
- 为什么即使不使用@ModelAttribute 注解,OrderController 也能正常工作?
- 为什么我们在 DesignTacoController 中需要 @ModelAttribute
- addIngredientsToModel 何时被调用?
- 我们可以合并 addIngredientsToModel 和 showDesignForm 吗?
我认为我缺少一些 Spring 的基本概念。希望有人能帮我解决这个问题。
非常感谢。
【问题讨论】:
-
我很困惑,当有 are 错误时,订单示例是否有效?
-
@crizzis 是的。这也是让我感到困惑的地方。 :)
标签: spring spring-mvc