Исключение IllegalStateException: ни BindingResult, ни простой целевой объект для имени компонента ‘design’ не доступны в качестве атрибута запроса

#spring-boot #spring-mvc #thymeleaf

#spring-boot #spring-mvc #thymeleaf

Вопрос:

Я новичок в spring и ссылался на Spring в действии 5ed. Я использую механизм шаблонов Thymeleaf. Ниже я перечислил 2 контроллера и 2 представления. Каждое представление имеет форму, и проверка формы выполняется с помощью валидатора hybernate для объекта домена.

Однако, когда проверка завершается неудачей в случае первого контролера (контроллера проектирования), я получаю следующее исключение Neither BindingResult nor plain target object for bean name 'design' available as request attribute . Но когда проверка завершается с ошибкой во втором контроллере (контроллере заказа), я не получаю никаких исключений.

В обоих случаях я не model.addAttribute внутри if(errors.hasErrors())

Контроллер проектирования

 @GetMapping
    public String showDesignForm(Model model) {
        List<Ingredient> ingredients = Arrays.asList(
                 new Ingredient("FLTO", "Flour Tortilla", Type.WRAP), .....
                );

        Type[] types = Ingredient.Type.values();
        for(Type type : types) {
            model.addAttribute(type.toString().toLowerCase(), filterByType(ingredients, type));
        }
        
        model.addAttribute("design", new Taco());
        return "design";
    }

    @PostMapping
    public String processDesign(@Valid Taco design, Errors errors) {
        if(errors.hasErrors()) {
            log.error("Errors in design");
            return "design";
        }
        log.info("Processing design "   design);
        return "redirect:orders/current";
    }
  

Дизайн

 <form method="POST" th:object="${design}">
            <div class="grid">
                <div class="ingredient-group" id="wraps">
                    <h3>Designate your wrap:</h3>
                    <div th:each="ingredient : ${wrap}">
                        <input name="ingredients" type="checkbox" th:value="${ingredient.id}"/>
                        <span th:text="${ingredient.name}">INGREDIENT</span> <br>
                    </div>
                </div>
            
            <h3>Name you taco creation</h3>
            <input type="text" th:field="*{name}"/><br> 
            <button>Submit your taco</button>
</form>
  

Контроллер заказа

 @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()) {
            log.error("Error in {}", order);
            return "orderForm";
        }
        log.info("Order sumbitted "   order);
        return "redirect:/";
    }
  

Форма заказа

 <form method="POST" th:action="@{/orders}" th:object="${order}">
            <h3>Deliver to</h3>
    
            <label for="name">Name: </label>
            <input type="text" th:field="*{name}"/>
            <br/>
    
            <input type="submit" value="Submit order"/>
</form>
  

Комментарии:

1. Можете ли вы попробовать заменить @Valid Taco design на @Valid @ModelAttribute("design") Taco design ?

2. Спасибо! Да, это работает. Но я хотел знать, почему я не получил такого же исключения в случае контроллера заказа.

3. Я думаю, это связано с именем класса. Order order совпадает с вашим ${order} , в то время Taco design как не совпадает с ${design} . Вы можете попробовать переименовать Taco класс в Design , чтобы быть уверенным. Я лично всегда добавляю аргумент @ModelAttribute , чтобы избежать такого рода «магии».