Java 如何从Thymeleaf模板设置对象字段?

Java 如何从Thymeleaf模板设置对象字段?,java,spring-boot,thymeleaf,Java,Spring Boot,Thymeleaf,我是Spring新手,我试图在Spring in action 5(Craig Walls)的帮助下学习它。我正在创建小型Spring Boot MVC应用程序。现在我对Thymeleaf有点问题 我将控制器、视图和模型作为POJO对象。当我试图从表单Intellij获取数据时,Idea告诉我这行中的ThymileAF视图有问题: Model import java.util.Date; import java.util.List; import javax.validation.constr

我是Spring新手,我试图在Spring in action 5(Craig Walls)的帮助下学习它。我正在创建小型Spring Boot MVC应用程序。现在我对Thymeleaf有点问题

我将控制器、视图和模型作为POJO对象。当我试图从表单Intellij获取数据时,Idea告诉我这行中的ThymileAF视图有问题:

Model
import java.util.Date;
import java.util.List;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import lombok.Data;


@Data
public class Taco {

    private Long id;

    private Date createdAt;

    @NotNull
    @Size(min=5, message="Name must be at least 5 characters long")
    private String name;

    @Size(min=1, message="You must choose at least 1 ingredient")
    private List<Ingredient> ingredients;


}

我注意到你的代码上有两件事

  • 我没有在您的表单上看到提交表单所需的
    th:action
  • formmethod=“POST”th:object=“${taco}”
    更改为
    formmethod=“POST”th:object=“${design}”

  • 尝试修复这两个问题,它应该会起作用。

    我在代码中发现了两件事:

  • 我在html中找不到您表单中的任何操作。您应该使用
    th:action
    标记添加操作
  • 在html中,您使用
    th:object=“${taco}”
    为html表单声明对象。但您不会在控制器中的model方法中添加“taco”对象,从中返回html设计。您应该在控制器方法中添加“taco”对象,如下所示

    model.addAttribute(“taco”,taco对象)


  • 我遇到了同样的问题

    我的解决方案是在Taco.java中为name添加getter。不知何故,lombok并没有在运行时自动生成getter

    th:object=“${taco}”
    应该是
    th:object=“${design}”

    无需更改
    th:action
    。来自教程

    如果再次查看视图中的标记,可以看到其method属性设置为POST。此外,没有声明action属性。这意味着提交表单时,浏览器将收集表单中的所有数据,并以HTTP POST请求的形式将其发送到服务器,发送路径与GET请求在表单/设计路径中显示的路径相同


    您的html第64行有什么内容?对不起。这一列第32列从这里开始,将
    更改为
    它可以工作,但输入错误正常,但另一个页面部分不工作(为什么我应该将taco更改为design?您指的是页面的另一部分是什么?您如何看到我从数据库中获取数据并在视图中显示这些数据,以及此构造成分,如果我将th:object替换为th:object=“${design}”我听不懂你们在说什么。看一下百里香的文档。谢谢你们的帮助。我解决了问题。你们是对的。
    <!DOCTYPE html>
    <html lang="en"
          xmlns="http://www.w3.org/1999/xhtml"
          xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Taco Cloud</title>
        <link rel="stylesheet" th:href="@{/styles.css}"/>
    
    </head>
    <body>
    
        <h1>Design your taco!</h1>
        <img src="../static/images/TacoCloud.png" alt="TacoCloud.png" th:src="@{/images/TacoCloud.png}">
    
        <form method="POST" th:object="${taco}">
            <div class="grid">
                <div class="ingredient-group" id="wraps">
                    <h3>Designate yor 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>
    
    
                <div class="ingredient-group" id="proteins">
                <h3>Pick your protein:</h3>
                <div th:each="ingredient: ${protein}">
                    <input name="ingredients" type="checkbox" th:value="${ingredient.id}"/>
                    <span th:text="${ingredient.name}">INGREDIENT</span>
                </div>
            </div>
    
    
                <div class="ingredient-group" id="cheeses">
                    <h3>Choose your cheese:</h3>
                    <div th:each="ingredient:${cheese}">
                        <input name="ingredients" type="checkbox" th:value="${ingredient.id}"/>
                        <span th:text="${ingredient.name}">INGREDIENT</span><br/>
                    </div>
                </div>
    
                <div class="ingredient-group" id="veggies">
                    <h3>Determine your veggies:</h3>
                    <div th:each="ingredient : ${veggies}">
                        <input name="ingredients" type="checkbox" th:value="${ingredient.id}"
                        />
                        <span th:text="${ingredient.name}">INGREDIENT</span><br/>
                    </div>
                </div>
                <div class="ingredient-group" id="sauces">
                    <h3>Select your sauce:</h3>
                    <div th:each="ingredient : ${sauce}">
                        <input name="ingredients" type="checkbox" th:value="${ingredient.id}"
                        />
                        <span th:text="${ingredient.name}">INGREDIENT</span><br/>
                    </div>
                </div>
            </div>
            <div>
                <h3>Name your taco creation:</h3>
                <input type="text" name="name"  th:field="*{name}"/> 
    
                <br/>
                <button>Submit your taco</button>
            </div>
    
        </form>
    
    </body>
    </html>
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.validation.Errors;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import tacos.Ingredient.Type;
    import tacos.Ingredient;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import tacos.Taco;
    import tacos.data.IngredientRepository;
    
    import javax.validation.Valid;
    
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;
    
    
    @Slf4j
    @Controller
    @RequestMapping("/design")
    public class DesignTacoController {
    
        private final IngredientRepository ingredientRepo;
    
        @Autowired
        public DesignTacoController(IngredientRepository ingredientRepo){
            this.ingredientRepo=ingredientRepo;
        }
    
    
        @GetMapping
        public String showDesignForm(Model model) {
    
            List<Ingredient> ingredients=new ArrayList<>();
            ingredientRepo.findAll().forEach(i->ingredients.add(i));
    
            Type[] types = Ingredient.Type.values();
            for (Type type : types) {
                model.addAttribute(type.toString().toLowerCase(),
                        filterByType(ingredients, type));
            }
    
            return "design";
        }
    
    
        private List<Ingredient> filterByType(
                List<Ingredient> ingredients, Type type) {
            return ingredients
                    .stream()
                    .filter(x -> x.getType().equals(type))
                    .collect(Collectors.toList());
        }
    
        @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";
        }
    
    }
    
    org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/design.html]")
    
    Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "design" - line 64, col 45)