Java 如何将对象从thymeleaf表单发送到MVC spring引导控制器
我有两个类(Employee和Project),它们有多对多的关系。我试图发送thymeleaf表单的内容,将(project)作为类对象,并发送一个包含员工列表的下拉列表。我可以在我的表单中检索员工列表,但当我将其提交给控制器保存时,列表中的非员工被保存。每次提交表单时,我应该能够节省一名员工 这是员工级别:Java 如何将对象从thymeleaf表单发送到MVC spring引导控制器,java,spring-mvc,spring-boot,thymeleaf,Java,Spring Mvc,Spring Boot,Thymeleaf,我有两个类(Employee和Project),它们有多对多的关系。我试图发送thymeleaf表单的内容,将(project)作为类对象,并发送一个包含员工列表的下拉列表。我可以在我的表单中检索员工列表,但当我将其提交给控制器保存时,列表中的非员工被保存。每次提交表单时,我应该能够节省一名员工 这是员工级别: @Entity @Table(name = "EMPLOYEE") public class Employee { @Id @Column(name = "EMPLOY
@Entity
@Table(name = "EMPLOYEE")
public class Employee {
@Id
@Column(name = "EMPLOYEE_ID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "FIRST_NAME")
private String firstName;
@Column(name = "LAST_NAME")
private String lastName;
@Column(name = "DOB")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date dob;
@Column(name = "HIRING_DATE")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date hiringDate;
@Column(name = "TERMINATION_DATE")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date terminationDate;
@Column(name = "TELEPHONE")
private String telephone;
@Column(name = "EMAIL")
private String email;
@Column(name = "JOB_TITLE")
private String jobTitle;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "MANAGER_ID")
private Employee manager;
@OneToOne(cascade=CascadeType.ALL)
private EmployeeInfo empInfo;
@ManyToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER)
@JoinTable(name = "EMPLOYEE_PROJECT", joinColumns = { @JoinColumn(name = "EMPLOYEE_ID") }, inverseJoinColumns = {
@JoinColumn(name = "PROJECT_ID") })
Set<Project> projects;
public Employee() {
super();
}
public Employee(Long id, String firstName, String lastName, String telephone, String email, String jobTitle) {
super();
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.telephone = telephone;
this.email = email;
this.jobTitle = jobTitle;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Date getDob() {
return dob;
}
public void setDob(Date dob) {
this.dob = dob;
}
public Date getHiringDate() {
return hiringDate;
}
public void setHiringDate(Date hiringDate) {
this.hiringDate = hiringDate;
}
public Date getTerminationDate() {
return terminationDate;
}
public void setTerminationDate(Date terminationDate) {
this.terminationDate = terminationDate;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getJobTitle() {
return jobTitle;
}
public void setJobTitle(String jobTitle) {
this.jobTitle = jobTitle;
}
public Set<Project> getProjects() {
return projects;
}
public void setProjects(Set<Project> projects) {
this.projects = projects;
}
public Employee getManager() {
return manager;
}
public void setManager(Employee manager) {
this.manager = manager;
}
public EmployeeInfo getEmpInfo() {
return empInfo;
}
public void setEmpInfo(EmployeeInfo empInfo) {
this.empInfo = empInfo;
}
}
@实体
@表(name=“EMPLOYEE”)
公营雇员{
@身份证
@列(name=“EMPLOYEE\u ID”)
@GeneratedValue(策略=GenerationType.IDENTITY)
私人长id;
@列(name=“FIRST_name”)
私有字符串名;
@列(name=“LAST_name”)
私有字符串lastName;
@列(name=“DOB”)
@日期时间格式(pattern=“yyyy-MM-dd”)
私人约会日期;
@列(name=“雇用日期”)
@日期时间格式(pattern=“yyyy-MM-dd”)
私人日期雇佣日期;
@列(name=“终止日期”)
@日期时间格式(pattern=“yyyy-MM-dd”)
私人日期终止日期;
@列(name=“电话”)
专用串电话;
@列(name=“EMAIL”)
私人字符串电子邮件;
@列(name=“职务”)
私有字符串职务;
@manytone(fetch=FetchType.EAGER)
@JoinColumn(name=“MANAGER\u ID”)
私人雇员经理;
@OneToOne(级联=级联类型.ALL)
私人雇员信息empInfo;
@ManyToMany(cascade={CascadeType.ALL},fetch=FetchType.EAGER)
@JoinTable(name=“EMPLOYEE\u PROJECT”,joinColumns={@JoinColumn(name=“EMPLOYEE\u ID”)},inverseJoinColumns={
@JoinColumn(name=“PROJECT\u ID”)}
设置项目;
公职人员(){
超级();
}
公共雇员(长id、字符串名字、字符串姓氏、字符串电话、字符串电子邮件、字符串职务){
超级();
this.id=id;
this.firstName=firstName;
this.lastName=lastName;
这个电话;
this.email=电子邮件;
this.jobTitle=jobTitle;
}
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
公共字符串getFirstName(){
返回名字;
}
public void setFirstName(字符串firstName){
this.firstName=firstName;
}
公共字符串getLastName(){
返回姓氏;
}
public void setLastName(字符串lastName){
this.lastName=lastName;
}
公开日期getDob(){
返回dob;
}
公共无效设置日期(日期日期){
this.dob=dob;
}
公共日期getHiringDate(){
返回雇佣日期;
}
公共作废setHiringDate(日期hiringDate){
this.hiringDate=雇用日期;
}
公共日期getTerminationDate(){
返回终止日期;
}
公共无效设置终止日期(日期终止日期){
this.terminationDate=终止日期;
}
公共字符串getTelephone(){
回电;
}
公用电话(串电话){
这个电话;
}
公共字符串getEmail(){
回复邮件;
}
公用电子邮件(字符串电子邮件){
this.email=电子邮件;
}
公共字符串getJobTitle(){
返回职务;
}
public void setJobTitle(字符串jobTitle){
this.jobTitle=jobTitle;
}
公共集getProjects(){
返回项目;
}
公共项目集合(集合项目){
这个项目=项目;
}
公共雇员管理人(){
退货经理;
}
公共经理(员工经理){
this.manager=经理;
}
公共雇员信息getEmpInfo(){
返回empInfo;
}
public void setEmpInfo(EmployeeInfo empInfo){
this.empInfo=empInfo;
}
}
这是一个项目类:
@Entity
@Table(name = "PROJECT")
public class Project {
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "PROJECT_TYPE")
private String projectType;
@Column(name = "PROJECT_NAME")
private String name;
@Column(name = "DESCRIPTION")
private String description;
@Column(name = "START_DATE")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date startDate;
@Column(name = "END_DATE")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date endDate;
@Column(name = "COST")
private Float cost;
@ManyToMany(mappedBy = "projects", fetch = FetchType.EAGER)
private Set<Employee> employees;
public Project() {
super();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getProjectType() {
return projectType;
}
public void setProjectType(String projectType) {
this.projectType = projectType;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public Float getCost() {
return cost;
}
public void setCost(Float cost) {
this.cost = cost;
}
public Set<Employee> getEmployees() {
return employees;
}
public void setEmployees(Set<Employee> employees) {
this.employees = employees;
}
}
@实体
@表(name=“项目”)
公共类项目{
@身份证
@列(name=“ID”)
@GeneratedValue(策略=GenerationType.IDENTITY)
私人长id;
@列(name=“项目类型”)
私有字符串类型;
@列(name=“项目名称”)
私有字符串名称;
@列(name=“DESCRIPTION”)
私有字符串描述;
@列(name=“开始日期”)
@日期时间格式(pattern=“yyyy-MM-dd”)
私人日期开始日期;
@列(name=“结束日期”)
@日期时间格式(pattern=“yyyy-MM-dd”)
私人日期结束日期;
@列(name=“成本”)
私人浮动成本;
@ManyToMany(mappedBy=“projects”,fetch=FetchType.EAGER)
私人雇员;
公共工程(){
超级();
}
公共长getId(){
返回id;
}
公共无效集合id(长id){
this.id=id;
}
公共字符串getProjectType(){
返回项目类型;
}
公共void setProjectType(字符串projectType){
this.projectType=项目类型;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共字符串getDescription(){
返回说明;
}
公共void集合描述(字符串描述){
this.description=描述;
}
公共日期getStartDate(){
返回起始日期;
}
公共作废设置开始日期(日期开始日期){
this.startDate=startDate;
}
公共日期getEndDate(){
返回结束日期;
}
公共无效设置结束日期(日期结束日期){
this.endDate=endDate;
}
公共成本{
退货成本;
}
公共成本(浮动成本){
成本=成本;
}
公共集合getEmployees(){
返回员工;
}
公共无效集合雇员(集合雇员){
这是。雇员=雇员;
}
}
这是主项目页面:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<h2>Projects List</h2>
<a href="#" th:href="@{/projects/new}" class="btn btn-primary"
role="button">Add New Project</a> <br> <br>
<table class="table table-striped">
<tr>
<th>Name</th>
<th>Cost</th>
<th>Start Date</th>
<th>End Date</th>
<th>Project Type</th>
<th></th>
<th></th>
</tr>
<tr th:each="project : ${projects}">
<td th:text="${project.name}"></td>
<td th:text="${project.cost}"></td>
<td th:text="${project.startDate}"></td>
<td th:text="${project.endDate}"></td>
<td th:text="${project.projectType}"></td>
<td><a th:href="@{'/project/' + ${project.id} + '/update'}">Update</a></td>
<td><a th:href="@{'/project/' + ${project.id} + '/addTeam'}">Add Team</a></td>
</tr>
</table>
</div>
</body>
</html>
入门:提供Web内容
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Getting Started: Serving Web Content</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<body>
<div class="container">
<h1>
<span th:text="${project.name }" th:remove="tag">title</span>
</h1>
<h3>
<span th:text="${project.id }" th:remove="tag">title</span>
</h3>
<br>
<h2>Add Project Team</h2>
<br>
<form class="form-group" th:object="${project}"
th:action="@{/projects/saveProject}" method="post">
<input th:type="hidden" name="id" th:field="${project.id}" />
<div class="form-group">
<label for="employees">Add Team:</label>
<select name="employees"
id="employees">
<option th:each="data:${employeesList}" th:value="${data.id}"
th:text="${data.firstName}" >Options</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Save</button>
<a href="#" th:href="@{/projects}" class="btn btn-danger"
role="button">Cancel</a>
</form>
</div>
</body>
</html>
@RequestMapping("project/{id}/addTeam")
public String addProjectTeam(@PathVariable String id, Model model) {
model.addAttribute("project", projectService.findById(Long.valueOf(id)));
model.addAttribute("employeesList", this.employeeService.getEmployees());
return "addTeam";
}
@PostMapping("/projects/saveProject")
public String saveOrUpdate(Model model, @RequestParam("project") Project project,
@RequestParam("employees") Set<Long> employeesIds)
{
Set<Employee> employees = new LinkedHashSet<Employee>();
if (project.getEmployees() != null && project.getEmployees().size() > 0) {
for (Employee emp : project.getEmployees()) {
employeesIds.add(emp.getId());
}
for (Long eId : employeesIds) {
Employee e = this.employeeService.findById(eId);
employees.add(e);
}
project.setEmployees(employees);
this.projectService.saveProject(project);
}
model.addAttribute("projects", projectService.getProjects());
return "redirect:/projects/";enter image description here
}
<select name="Employee">
<option value="Id">David</option>
<option value="Id">Peter</option>
</select>
@RequestMapping("/getProjectAndEmployee")
public String getProjectAndEmployee(Model model) {
List<YourEmployeeEntityClass> employees = //your code to get the employee
List<YourProjectEntityClass> project = //your code to get project
model.addAttribute("employees",employees);
model.addAttribute("project",project);
}
<select>
<option th:each="data:${employees}" th:value="${data.employee_id}" th:text="${data.employee_name}"> </option>
</select>
@PostMapping("/projects/saveProject")
public String saveOrUpdate(Model model, @RequestParam("project") Project project,
@RequestParam("employee_id")String employee_id ) {
//here you've employee_id , get the employee's details on the basis of this id from your DB
}