0

I am new to Spring and reading "Spring in Action" (which is a good book indeed). Here I encountered a problem in one of the example in this book that confused me a lot. In this example, there are two controllers correspond to two paths respectively. One is DesignTacoController and the other one is OrderController.

During my own trial on this example, I firstly copied OrderController which is a very simple class like below. This piece of code works perfectly when there is/isn't error input on web page.

@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:/"; } } 

And then I implemented DesignTacoController by myself according to OrderController above

@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 } 

With this implementation, it works fine when there is no error inputs. However, if I input something against the validator, I will get a

java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'design' available as request attribute 

By searching on stackoverflow (this question) and checking the original example code on github, I found this class should be implemented like this

@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 } 

Here comes my questions,

  1. Why does OrderController work with no problem even without using @ModelAttribute annotation?
  2. Why do we need @ModelAttribute in DesignTacoController
  3. When will addIngredientsToModel be called?
  4. Can we merge addIngredientsToModel and showDesignForm?

I think I am lacking of some basic concepts of Spring. Hopefully somebody can help me out with this.

Thank you very much.

2
  • I'm confused, does the order example work when there are errors? Commented Apr 12, 2021 at 17:23
  • @crizzis Yes. And that is what also confused me. :) Commented Apr 13, 2021 at 1:20

1 Answer 1

2

When the @ModelAttribute is used at method level the purpose is to add one or more model attributes to the model. Here adding this

to the model. model.addAttribute(type.toString().toLowerCase(), filterByType(ingredients, type)); }

Thing is Spring creates model objects before any request mapping. So addIngredientsToModel method will get invoke before any Handler methods.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.