页面上的Spring MVC + Thymeleaf div没有生成 [英] Spring MVC + Thymeleaf divs on the page are not generated

查看:22
本文介绍了页面上的Spring MVC + Thymeleaf div没有生成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Spring 的新手,我正在尝试使用 Spring MVC 和 Thymeleaf 制作 Web 应用程序.我有一个带有用于创建自定义比萨饼和相应控制器的表单的页面.用户可以输入披萨的名称,所以我添加了输入验证.在我输入无效名称之前,一切正常,但是当我返回页面的新视图时,带有复选框的 div 不会出现,它们只是不会生成.刷新后我的模型似乎是空的,但我不明白如何调试它,我在 intellij 想法中的快捷方式不起作用.

创建披萨控制器:

@Slf4j@控制器@RequestMapping("/create")公共类 CreatePizzaController {@GetMapping公共字符串 showCreationForm(模型模型){列出<成分>成分 = Arrays.asList(new Ingredient("CLS22", "Classic base 22cm", Ingredient.Type.BASIC),new Ingredient("CLS30", "Classic base 30cm", Ingredient.Type.BASIC),new Ingredient("PEPE", "Pepperoni", Ingredient.Type.MEAT),new Ingredient("HAM", "Ham", Ingredient.Type.MEAT),new Ingredient("CHMPG", "Champignons", Ingredient.Type.VEGGIES),new Ingredient("CUCU", "Cucumbers", Ingredient.Type.VEGGIES),new Ingredient("PARM", "Parmesan cheese", Ingredient.Type.CHEESE),new Ingredient("MOZ", "Mozzarella cheese", Ingredient.Type.CHEESE),new Ingredient("BARBS", "烧烤酱", Ingredient.Type.SAUCE),new Ingredient("TOMAS", "番茄酱", Ingredient.Type.SAUCE));Ingredient.Type[] types = Ingredient.Type.values();for(成分.类型类型:类型){model.addAttribute(type.toString().toLowerCase(), filterByType(ingredients, type));}model.addAttribute("create", new Pizza());返回创建";}@PostMappingpublic String processCreation(@Valid @ModelAttribute("create") 比萨披萨,BindingResult 结果){if(result.hasErrors()){返回创建";}//保存创建...log.info("处理创建:"+pizza);返回重定向:/订单/当前";}私人清单<成分>filterByType(List成分,Ingredient.Type类型){列出<成分>过滤 = 新的 ArrayList<>();对于(成分成分:成分){if(ingredient.getType() == type){过滤.添加(成分);}}返回过滤;}}

create.html:

<html lang="en"><html xmlns="http://www.w3.org/1999/xhtml";xmlns:th=http://www.thymeleaf.org"><头><元字符集=UTF-8"><title>标题</title><link rel="样式表";th:href="@{/styles/style.css}";/><身体><h3>创建您的披萨:</h3><img th:src="@{/images/pizza_logo.jpg}"宽度=200"高度=200"/><form method="post";th:object="${create}"><div class="grid"><div class="ingredient-group";id=基础"><h3>选择基本的:</h3><div th:each=成分:${basic}"><输入名称=成分"类型=收音机"检查 th:value=${ingredient.id}"/><span class="checktext"th:text=${ingredient.name}">INGREDIENT</span><br/>

<div class="ingredient-group";id=肉"><h3>选择肉类:</h3><div th:each="成分:${meat}"><输入名称=成分"类型=复选框"th:value=${ingredient.id}"/><span class="checktext";th:text=${ingredient.name}">INGREDIENT</span><br/>

<div class="ingredient-group";id=蔬菜"><h3>选择蔬菜:</h3><div th:each="ingredient : ${veggies}"><输入名称=成分"类型=复选框"th:value=${ingredient.id}"/><span class="checktext";th:text=${ingredient.name}">INGREDIENT</span><br/>

<div class="ingredient-group";id=酱汁"><h3>选择酱汁:</h3><div th:each=成分:${sauce}"><输入名称=成分"类型=复选框"th:value=${ingredient.id}"/><span class="checktext";th:text=${ingredient.name}">INGREDIENT</span><br/>

<div class="ingredient-group";id=奶酪"><h3>选择奶酪:</h3><div th:each=成分:${cheese}"><输入名称=成分"类型=复选框"th:value=${ingredient.id}"/><span class="checktext";th:text=${ingredient.name}">INGREDIENT</span><br/>

<div class="submit-button"><h3>为您的披萨命名:</h3><输入类=提交字段"类型=文本"th:field="*{name}";/><span class="validationError";th:if="${#fields.hasErrors('name')}";th:errors="*{name}">Error</span><br/><button>提交您的披萨</button>

</表单></html>

无效输入前的页面

无效输入后的pafe

github 上的完整代码

解决方案

你的问题在这里:

@PostMappingpublic String processCreation(@Valid @ModelAttribute("create") 比萨披萨,BindingResult 结果){if(result.hasErrors()){返回创建";}//保存创建...log.info("处理创建:"+pizza);返回重定向:/订单/当前";}

您需要在返回create"之前再次添加您的模型属性.Thymeleaf 没有错,模型只是缺少属性,无法填充复选框.这样的事情应该可以工作:

@GetMapping公共字符串 showCreationForm(模型模型){addCreationFormModelAttributes(model, new Pizza());返回创建";}@PostMappingpublic String processCreation(模型模型,@Valid @ModelAttribute(create")比萨披萨,BindingResult结果){if(result.hasErrors()){addCreationFormModelAttributes(模型,披萨);返回创建";}//保存创建...log.info("处理创建:"+pizza);返回重定向:/订单/当前";}私有静态 addCreationFormModelAttributes(模型模型,比萨披萨){列出<成分>成分 = Arrays.asList(new Ingredient("CLS22", "Classic base 22cm", Ingredient.Type.BASIC),new Ingredient("CLS30", "Classic base 30cm", Ingredient.Type.BASIC),new Ingredient("PEPE", "Pepperoni", Ingredient.Type.MEAT),new Ingredient("HAM", "Ham", Ingredient.Type.MEAT),new Ingredient("CHMPG", "Champignons", Ingredient.Type.VEGGIES),new Ingredient("CUCU", "Cucumbers", Ingredient.Type.VEGGIES),new Ingredient("PARM", "Parmesan cheese", Ingredient.Type.CHEESE),new Ingredient("MOZ", "Mozzarella cheese", Ingredient.Type.CHEESE),new Ingredient("BARBS", "烧烤酱", Ingredient.Type.SAUCE),new Ingredient("TOMAS", "番茄酱", Ingredient.Type.SAUCE));Ingredient.Type[] types = Ingredient.Type.values();for(成分.类型类型:类型){model.addAttribute(type.toString().toLowerCase(), filterByType(ingredients, type));}model.addAttribute(创建",披萨);}

I am new to Spring and I am trying to make web application using Spring MVC and Thymeleaf. I have the page with the form to create custom pizza and corresponding controller. User can enter the name of the pizza so I added input validation. Before I enter invalid name everything is ok, but then when I return a new view of the page, divs with my checkboxes do not appear, they just don't generate. It seems like my Model after refreshing is empty but I don't understand how I could debug this, my shortcuts in intellij idea just don't work.

CreatePizzaController:

@Slf4j
@Controller
@RequestMapping("/create")
public class CreatePizzaController {
    @GetMapping
    public String showCreationForm(Model model){
        List<Ingredient> ingredients = Arrays.asList(
                new Ingredient("CLS22", "Classic base 22cm", Ingredient.Type.BASIC),
                new Ingredient("CLS30", "Classic base 30cm", Ingredient.Type.BASIC),
                new Ingredient("PEPE", "Pepperoni", Ingredient.Type.MEAT),
                new Ingredient("HAM", "Ham", Ingredient.Type.MEAT),
                new Ingredient("CHMPG", "Champignons", Ingredient.Type.VEGGIES),
                new Ingredient("CUCU", "Cucumbers", Ingredient.Type.VEGGIES),
                new Ingredient("PARM", "Parmesan cheese", Ingredient.Type.CHEESE),
                new Ingredient("MOZ", "Mozzarella cheese", Ingredient.Type.CHEESE),
                new Ingredient("BARBS", "Barbecue sauce", Ingredient.Type.SAUCE),
                new Ingredient("TOMAS", "Tomato sauce", Ingredient.Type.SAUCE)
                );

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

    @PostMapping
    public String processCreation(@Valid @ModelAttribute("create") Pizza pizza, BindingResult result){
        if(result.hasErrors()){
            return "create";
        }
        //Save creation...
        log.info("Processing creation: " + pizza);
        return "redirect:/orders/current";
    }

    private List<Ingredient> filterByType(List<Ingredient> ingredients, Ingredient.Type type) {
        List<Ingredient> filtered = new ArrayList<>();
        for (Ingredient ingredient:ingredients){
            if(ingredient.getType() == type){
                filtered.add(ingredient);
            }
        }
        return filtered;
    }
}

create.html:

<!DOCTYPE html>
<html lang="en">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" th:href="@{/styles/style.css}" />
</head>
<body>
<h3>Create your pizza:</h3>
<img th:src="@{/images/pizza_logo.jpg}" width="200" height="200"/>

<form method="post" th:object="${create}">
    <div class="grid">
        <div class="ingredient-group" id="basics">
            <h3>Choose the basic: </h3>
            <div th:each="ingredient : ${basic}">
                <input name="ingredients" type="radio" checked th:value="${ingredient.id}"/>
                <span class="checktext" th:text="${ingredient.name}">INGREDIENT</span><br/>
            </div>
        </div>
        <div class="ingredient-group" id="meat">
            <h3>Choose meat: </h3>
            <div th:each="ingredient : ${meat}">
                <input name="ingredients" type="checkbox" th:value="${ingredient.id}"/>
                <span class="checktext" th:text="${ingredient.name}">INGREDIENT</span><br/>
            </div>
        </div>
        <div class="ingredient-group" id="veggies">
            <h3>Choose vegetables: </h3>
            <div th:each="ingredient : ${veggies}">
                <input name="ingredients" type="checkbox" th:value="${ingredient.id}"/>
                <span class="checktext" th:text="${ingredient.name}">INGREDIENT</span><br/>
            </div>
        </div>
        <div class="ingredient-group" id="sauce">
            <h3>Choose sauce: </h3>
            <div th:each="ingredient : ${sauce}">
                <input name="ingredients" type="checkbox" th:value="${ingredient.id}"/>
                <span class="checktext" th:text="${ingredient.name}">INGREDIENT</span><br/>
            </div>
        </div>
        <div class="ingredient-group" id="cheese">
            <h3>Choose cheese: </h3>
            <div th:each="ingredient : ${cheese}">
                <input name="ingredients" type="checkbox" th:value="${ingredient.id}"/>
                <span class="checktext" th:text="${ingredient.name}">INGREDIENT</span><br/>
            </div>
        </div>
    </div>
    <div class="submit-button">
        <h3>Name your pizza:</h3>
        <input class="submit-field" type="text" th:field="*{name}" />
        <span class="validationError"
              th:if="${#fields.hasErrors('name')}"
              th:errors="*{name}">Error</span>
        <br/>
        <button>Submit your pizza</button>
    </div>
</form>
</body>
</html>

page before invalid input

pafe after invalid input

full code on github

解决方案

Your problem is here:

@PostMapping
public String processCreation(@Valid @ModelAttribute("create") Pizza pizza, BindingResult result){
    if(result.hasErrors()){
        return "create";
    }
    //Save creation...
    log.info("Processing creation: " + pizza);
    return "redirect:/orders/current";
}

You need to add your model attributes again before returning "create". Thymeleaf isn't incorrect, the model is simply missing attributes and can't populate the checkboxes. Something like this should work:

@GetMapping
public String showCreationForm(Model model){
    addCreationFormModelAttributes(model, new Pizza());
    return "create";
}

@PostMapping
public String processCreation(Model model, @Valid @ModelAttribute("create") Pizza pizza, BindingResult result){
    if(result.hasErrors()){
        addCreationFormModelAttributes(model, pizza);
        return "create";
    }
    //Save creation...
    log.info("Processing creation: " + pizza);
    return "redirect:/orders/current";
}

private static addCreationFormModelAttributes(Model model, Pizza pizza) {
    List<Ingredient> ingredients = Arrays.asList(
            new Ingredient("CLS22", "Classic base 22cm", Ingredient.Type.BASIC),
            new Ingredient("CLS30", "Classic base 30cm", Ingredient.Type.BASIC),
            new Ingredient("PEPE", "Pepperoni", Ingredient.Type.MEAT),
            new Ingredient("HAM", "Ham", Ingredient.Type.MEAT),
            new Ingredient("CHMPG", "Champignons", Ingredient.Type.VEGGIES),
            new Ingredient("CUCU", "Cucumbers", Ingredient.Type.VEGGIES),
            new Ingredient("PARM", "Parmesan cheese", Ingredient.Type.CHEESE),
            new Ingredient("MOZ", "Mozzarella cheese", Ingredient.Type.CHEESE),
            new Ingredient("BARBS", "Barbecue sauce", Ingredient.Type.SAUCE),
            new Ingredient("TOMAS", "Tomato sauce", Ingredient.Type.SAUCE)
    );

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

这篇关于页面上的Spring MVC + Thymeleaf div没有生成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆