当前位置: 首页 > 知识库问答 >
问题:

通过Thymeleaf模板传递SPRING应用程序中更改的子对象的问题

云季萌
2023-03-14

我正在开发测试任务-报价书(未经授权)。我有两个实体:报价和作者。这里有代码:

@Entity
@Table(name="authors")
public class Author {
    @Id
    @SequenceGenerator(name="author_id_seq", sequenceName="author_id_seq", allocationSize=1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "author_id_seq")
    @Column(name = "id")
    private long id;

    @Column(name = "nick_name")
    private String nickName;

    public Author() {
    }

    public Author(long id, String nickName) {
        this.id = id;
        nickName = nickName;
    }
/*
Getters and Setters
*/
}

报价:

@Entity
@Table(name = "quotes")
public class Quote {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "quotes_id_seq")
    @SequenceGenerator(name="quotes_id_seq", sequenceName="quotes_id_seq", allocationSize=1)
    @Column(name = "id")
    private long id;
    @Column(name = "content")
    private String content;
   // @Temporal(TemporalType.DATE)
    @Column(name = "date")
    private LocalDate date;
    @ManyToOne
    @JoinColumn(name = "author")
    private Author author;

    public Quote() {
    }

    public Quote(long id, String content, LocalDate date, Author author) {
        this.id = id;
        this.content = content;
        this.date = date;
        this.author = author;
    }
/*
Getters and Setters
*/
}

我的Thymeleaf模板包含带有两个输入字段(for Quote.Content和for Quote.Author.Nickname)的form,以及带有现有作者的select。我想看到这样的行为,当我为author、content填充输入时,如果authors表中不存在author,我的应用程序在这个表中添加来自输入昵称和生成ID的指定值的行。但问题是从Thymeleaf模板中得到我意想不到的结果。Template将带author的Quote对象传递给Controll,该对象的昵称为null而不是来自我输入的值。有我的表单的thymeleaf模板代码:

 <form action="#" th:action="@{/newQuote}" th:object="${quote}" method="post">
                <div class="form-row">
                    <div class="form-group col-md-3">
                        <label class="sr-only" for="inputNick">Nick Name</label>
                        <!--/*@thymesVar id="author" type="hello.entity.Author"*/-->
                        <input type="text" class="form-control" id="inputNick" th:field="*{author.nickName}"
                               placeholder="enter Nick Name">
                    </div>
                    <div class="form-group col-md-6">
                        <select id="nickNames">
                            <th:block th:each="author : ${allAuthors}">
                                <option th:text="${author.nickName}">Nick Name</option>
                            </th:block>
                        </select>
                    </div>
                    <div class="form-group col-md-12">
                        <label for="postContent">Your Quote:</label>
                        <input type="text" class="form-control" id="postContent" th:field="*{content}"
                               placeholder="quote text">
                    </div>
                </div>

                    <div class="form-group col-md-2">
                        <input type="submit" value="Add Quote"/>
                    </div>
                    <div class="form-group col-md-2">
                        <input type="reset" value="Reset"/>
                    </div>

            </form>
@GetMapping("/newQuote")
    public String showAuthors(Model model){
        model.addAttribute("allAuthors",authorService.findAll());
        model.addAttribute("quote", new Quote());
        return "newQuote";
    }

    @PostMapping("/newQuote")
    public String addQuote (@ModelAttribute Quote quote) {
        quote.setDate(LocalDate.now());
        quoteRepository.save(quote);
        return "redirect:/";
    null

我知道我可以用字段昵称insteadof author字段创建DTO类并在Controller的postmapping方法中将其转换为我的实体类。但我认为这是“不好的练习”的方式。我想,当我试图更改author对象并将其从thymeleaf传递到Controller时,我可能做了错误的步骤。而且我也认为,在这种情况下,没有办法实现这个逻辑。我不知道真相在哪里。请帮我找到它。

附言:对不起,我的英语不好

共有1个答案

养翔
2023-03-14

答案是如何同时添加一个引号和它的作者。因为我们的作者不存在,所以选择方法是不可能的。实现这一点的简单方法是更改quote实体并将@Cascade(CascadeType.Persist)添加到quote中的author字段。这将自动坚持作者与您的报价。

这些将是完成此任务所需的对代码的更改。

更新

@PostMapping("/newQuote")
public String addQuote (@ModelAttribute Quote quote,
                        @RequestParam("nickName") String nickName) {
    // This will automatically persist your quote and it's author.
    quote.setDate(LocalDate.now());
    Author author = new Author();
    author.setNickName(nickName);
    quoteRepository.save(quote);
}

报价实体

@Entity
@Table(name = "quotes")
public class Quote {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "quotes_id_seq")
    @SequenceGenerator(name="quotes_id_seq", sequenceName="quotes_id_seq", allocationSize=1)
    @Column(name = "id")
    private long id;

    @Column(name = "content")
    private String content;

    @Column(name = "date")
    private LocalDate date;

    @ManyToOne
    @Cascade(CascadeType.PERSIST)
    @JoinColumn(name = "author")
    private Author author;

    // Getters and Setters
}

重要的是,确保注意到我们正在向作者字段添加一个新的注释@cascade(CascadeType.persist)

HTML

<form action="#" th:action="@{/newQuote}" th:object="${quote}" method="post">
    <div class="form-row">
        <div class="form-group col-md-3">
            <label class="sr-only" for="inputNick">Nick Name</label>
            <!--/*@thymesVar id="author" type="hello.entity.Author"*/-->
            <input type="text" name="nickName" class="form-control" id="inputNick" placeholder="enter Nick Name"/>
        </div>
        <div class="form-group col-md-12">
            <label for="postContent">Your Quote:</label>
            <input type="text" class="form-control" id="postContent" th:field="*{content}" placeholder="quote text"/>
        </div>
   </div>
   <div class="form-group col-md-2">
       <input type="submit" value="Add Quote"/>
   </div>
   <div class="form-group col-md-2">
      <input type="reset" value="Reset"/>
   </div>
</form>
 类似资料:
  • 我有一个Spring Boot应用程序,我在pom中定义了我的thymeleaf依赖项。包含以下行的xml: 因此,当我启动应用程序并打印预定义的bean名称时,我会看到这些bean(我认为这对thymeleaf正常运行很重要): 模板引擎 thymeleafResourceResolver thymeleafViewResolver 项目结构如下所示: 我在fragments.html中定义了一

  • 是否可以通过context将对象(比方说User(包含3个字符串属性-name、password、detail)传递给thymeleaf模板,并从模板中访问它的属性,例如 ? 如果是这样,我该怎么做? 匿名用户 如果你正在使用spring和thymeleaf,那么它们应该像魅力一样为你工作。在这种情况下,它非常简单: 其中myTemplate引用,其内容如下所示: 和我的实体 和我使用的沉香酒的版

  • > 控制器只是实例化这个对象并返回。 在输出中,我看到Date对象的默认表示形式是一个整数(可能是历元的毫秒) 是否有任何方法可以将日期对象的默认jsonification更改为ISO字符串或任何其他字符串? 编辑: 我对Spring和Spring Boot很陌生。我使用的模板来自spring网站上的一个示例应用程序。JSONification是通过Jackson完成的。Rest一下,一般来说,我

  • 我正在使用下面的配置创建一个docker映像。一旦image准备就绪,我想要将JAVA_OPTS传递给我的docker容器,这样它就可以传递给我的Spring Boot应用程序。每当我尝试打开容器时,我就会得到“Runtime create Failed:CONTAINER_Linux.go:348:starting container process caused”exec:\“java$JAV

  • 问题内容: 是否可以通过Java通过引用传递对象 就像在C#中一样 问题答案: 不,这在Java中是不可能的。 在Java中,方法的所有参数均按值传递。注意非原始型的的变量,它们是对对象的引用,也由值来传递:在这种情况下, 参考 是 由值来传递 。请注意,按值传递引用与按引用传递不同。

  • 我遵循了这篇Thymeleaf教程“使用Thymeleaf在Spring生成丰富的HTML电子邮件”,使用Thymeleaf模板生成了一封电子邮件。一切正常,但我无法访问应用程序中其他地方使用的ApplicationContext bean。 更具体地说,在我的电子邮件模板中,我希望有如下内容: 其中“myBean”是一个@组件。这可能吗?我不是在寻找像这样的解决方法 其中bean作为变量添加到模