不能将对象从一个thymeleaf视图传递到另一个thymeleaf视图

vcudknz3  于 2021-07-23  发布在  Java
关注(0)|答案(0)|浏览(206)

我是spring的新手,正在开发一个springmvc+thymeleaf应用程序来跟踪个人开支。我有一个显示费用列表的页面,在单击任何给定费用的“更新”时,它将在另一个页面上显示一个预填充的表单,其中包含该费用的信息。我遇到的问题是,我想将这个expense对象转发到第二个页面,但是由于数据已经从我的第一个页面的数据库中获取,所以我不想再从spring数据jpa存储库中获取它。
我想我的目标中不寻常的一部分是我试图通过这样的物体:
控制器->thymeleaf->控制器->thymeleaf
当控制器将一个费用对象发送到“费用列表”页面时,我正在尝试将同一个对象(或者只是一个费用,甚至更好)重新发送回控制器,这样它就会在我的第二个表单页面中填充模型。
我的支出实体:

package com.williampoletto.expensetracker.entity;

import java.time.LocalDate;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@EqualsAndHashCode(of= "id")
@ToString(exclude="categories")
@Entity
@Table
public class Expense {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY )
    private int id;

    @NotBlank
    private String description;

    @NotNull
    private double value;

    @NotNull
    private LocalDate date;

    private String note;

    @ManyToOne
    private User user;

    @ManyToMany(cascade=CascadeType.PERSIST)
    @JoinTable(
            name="expense_category",
            joinColumns=@JoinColumn(name="expense_id"),
            inverseJoinColumns=@JoinColumn(name="category_id"))
    private Set<Category> categories;

    public void addCategory(Category category) {
        categories.add(category);
    }

    public void removeCategory(Category category) {
        categories.remove(category);
    }

    public Expense(int id, @NotBlank String description, @NotNull double value, @NotNull LocalDate date,
            String note, Set<Category> categories) {
        super();
        this.id = id;
        this.description = description;
        this.value = value;
        this.date = date;
        this.note = note;
        this.categories = categories;
    }

}

我的桌面:

<table class="table table-bordered table-striped">
        <thead class="thead-dark">
            <tr>
                <th>Description</th>
                <th>Value</th>
                <th>Category</th>
                <th>Note</th>
                <th>Date</th>
                <th>Action</th>
            </tr>
        </thead>
        <tbody>
            <tr th:each="expense : ${expenses}">
                <td th:text="${expense.description}"/>
                <td th:text="${expense.value}"/>
                <td>
                    <div th:each="category : ${expense.categories}">
                        <p th:text ="${category.name}"></p>
                    </div>
                </td>
                <td th:text="${expense.note}"/>
                <td th:text="${expense.date}"/>
                <td>
                    <form th:action="@{/expenses/showUpdateForm}" th:object="${expense}" method="POST">
                        <input type="text" name="expense" th:value="${expense.id}">
                        <input type="text" name="expenseDescription" th:value="${expense.description}">
                        <input type="text" name="expenseValue" th:value="${expense.value}">
                        <input type="text" name="expenseDate" th:value="${expense.date}">
                        <input type="text" name="expenseNote" th:value="${expense.note}">
                        <input type="text" name="expenseCategories" th:value="${expense.categories}">
                        <button th:if="${expense.user != null}" type="submit" class="btn btn-info btn-sm">Update</button>
                    </form>
                    <a th:href="@{/expenses/delete(expenseId=${expense.id})}" 
                        class="btn btn-danger btn-sm"
                        onclick="if (!(confirm('Are you sure you want to delete this expense?'))) return false">Delete</a>
                </td>
        </tbody>
    </table>

控制器的my/list和/showupdateform代码:

@GetMapping("/list")
    public String list(@AuthenticationPrincipal UserDetailsImpl userDetails, Model model) {

        Set<Expense> expenses = expenseService.findAll(userDetails.getUserId());

        model.addAttribute("expenses", expenses);

        return "expenses";
    }

    @PostMapping("/showUpdateForm")
    public String showFormForUpdate(@RequestParam("expenseId") int expenseId,
                                    @RequestParam("expenseDescription") String expenseDescription,
                                    @RequestParam("expenseValue") double expenseValue,
                                    @RequestParam("expenseDate") String expenseDate,
                                    @RequestParam("expenseNote") String expenseNote,
                                    @RequestParam("expenseCategories") Set<Category> expenseCategories,
                                    Model model) {

        Expense expense = new Expense
                (expenseId, expenseDescription, expenseValue, expenseDate, expenseNote, expenseCategories);

        model.addAttribute("expense", expense);

        return "/expense-form";

    }

我的最终表单页:

<form th:action="@{/expenses/save}" th:object="${expense}" method="POST">
        <input type="hidden" th:field="*{id}">
        <label>Description</label>
        <input type="text" th:field="*{description}" class="form-control mb-4 col-4" placeholder="Description">
        <label>Value</label>
        <input type="text" th:field="*{value}" class="form-control mb-4 col-4" placeholder="Value">
        <label>Date</label>
        <input type="text" th:field="*{date}" class="form-control mb-4 col-4" placeholder="Date">
        <label>Note</label>
        <input type="text" th:field="*{note}" class="form-control mb-4 col-4" placeholder="Note">
        <label>Categories</label>
        <input type="hidden"
            th:each="category : *{categories}"
            th:value="${category.id}"
            th:field="*{categories}"
            th:text="${category.name}"/>
        <button type="submit" class="btn btn-success col-2 mb-2">Save</button>
    </form>

我尝试过:
而不是发送一个对象,而是发送您在mythymeleaf表中看到的单个值。问题是,我的费用实体有localdate、user(另一个实体)和set属性,所以在将它们转换为控制器端的费用对象时遇到了问题。理想情况下,我希望编写这样的内容来简单地传递对象,但是这个示例发送一个tostring:

<form th:action="@{/expenses/showUpdateForm}" th:object="${expense}" method="POST">
   <input type="text" name="expense" th:value="${expense}">
</form>

尝试使用/showupdateform的参数从模型中获取expenses对象:

@RequestAttribute("expenses") Set<Expense> expenses

尝试在/showupdateform中检索如下对象,目的与2相同:

Set<Expense> expenses = (Set<Expense>) model.getAttribute("expenses");

尝试在控制器中使用redirectattributes,我发现这对于在控制器之间传递对象很有用,但在我的例子中可能不是:

@GetMapping("/showUpdateForm")
public String showFormForUpdate(Model model, RedirectAttributes attributes) {

   attributes.addAttribute("expenses");

   return "/expense-form";

    }

无论如何,我不知道如何做到这一点,我将感谢任何关于这个问题的光!我知道我可以通过简单地将一个id从视图发送到控制器来很容易地解决这个问题,然后我就可以使用该id对对象执行存储库搜索,但是这对数据库来说会很麻烦,因为数据已经存在,并且是在前一页中获取的。

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题