我是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对对象执行存储库搜索,但是这对数据库来说会很麻烦,因为数据已经存在,并且是在前一页中获取的。
暂无答案!
目前还没有任何答案,快来回答吧!