我想通过使用Thymeleaf处理的html表单在Spring中生成或绑定Project对象。到目前为止,一切正常,只有rolesNeeded列表字段可以通过勾选复选框来填充角色,目前还不起作用。

项目类

package com.floriantoenjes.instateam.model;

import javax.persistence.*;
import java.util.List;

@Entity
public class Project {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String name;
    private String description;
    private String status;

    @ManyToMany
    private List<Role> rolesNeeded;

    @ManyToMany
    private List<Collaborator> collaborators;

    public Project() {
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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 String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public List<Role> getRolesNeeded() {
        return rolesNeeded;
    }

    public void setRolesNeeded(List<Role> rolesNeeded) {
        this.rolesNeeded = rolesNeeded;
    }

    public List<Collaborator> getCollaborators() {
        return collaborators;
    }

    public void setCollaborators(List<Collaborator> collaborators) {
        this.collaborators = collaborators;
    }
}


角色类

package com.floriantoenjes.instateam.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Role {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;

    public Role() {
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}


控制器

package com.floriantoenjes.instateam.web.controller;

import com.floriantoenjes.instateam.model.Project;
import com.floriantoenjes.instateam.model.Role;
import com.floriantoenjes.instateam.service.ProjectService;
import com.floriantoenjes.instateam.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;

@Controller
public class ProjectController {
    @Autowired
    ProjectService projectService;

    @Autowired
    RoleService roleService;

    @RequestMapping("/add")
    public String newProjectForm(Model model) {
        List<Role> roles =  roleService.findAll();

        model.addAttribute("project", new Project());
        model.addAttribute("roles", roles);

        return "edit_project";
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String addProject(Project project) {
        projectService.save(project);
        return "redirect:/index";
    }

}


模板

<!DOCTYPE html>
<html>
    <head th:replace="layout :: head('Edit Project')"></head>
    <body>
        <header>
            <div class="container">
                <div class="site-header">
                    <a class="logo" href="index.html">InstaTeam</a>
                    <a class="new-project button icon-left" href="#"><i class="material-icons">add</i> New Project</a>
                </div>
            </div>
        </header>
        <nav>
            <ul>
                <li class="selected"><a href="index.html">Projects</a></li>
                <li><a href="collaborators.html">Collaborators</a></li>
                <li><a href="roles.html">Roles</a></li>
            </ul>
        </nav>
        <section>
            <div class="container wrapper">
                <form th:object="${project}" action="" method="post">
                    <div>
                        <label for="project_name"> Project Name:</label>
                        <input type="text" th:field="*{name}" name="project_name"/>
                    </div>
                    <div>
                        <label for="project_description">Project Description:</label>
                        <textarea rows="4" th:field="*{description}" name="project_description"></textarea>
                    </div>
                    <div>
                        <label for="project_status">Project Status:</label>
                        <div class="custom-select">
                        <span class="dropdown-arrow"></span>
                            <select th:field="*{status}" name="project_status">
                                <option value="active">Active</option>
                                <option value="archived">Archived</option>
                                <option value="not_started">Not Started</option>
                            </select>
                        </div>
                    </div>
                    <div>
                        <label for="project_roles">Project Roles:</label>
                        <ul class="checkbox-list">
                            <li th:each="role : ${roles}">
                                <input type="checkbox" th:field="*{rolesNeeded}" name="project_roles" th:value="${role.id}"/>
                                <span class="primary" th:text="${role.name}"></span>
                            </li>
                        </ul>
                    </div>
                    <div class="actions">
                        <input type="submit" value="Save" class="button"/>
                        <a href="#" class="button button-secondary">Cancel</a>
                    </div>
                </form>
            </div>
        </section>
    </body>
</html>


如您所见,rolesNeeded是一个集合,我希望能够选中角色的复选框,然后在提交表单时生成一个Project对象,并将其角色分配给“ rolesNeeded”集合。正如我现在用*{rolesNeeded}{role.id}指出的那样,它不起作用。

现在,我得到以下错误:


  发生意外错误(类型=错误请求,状态= 400)。
  对象=“项目”的验证失败。错误计数:1


希望有人对如何解决这个问题或我如何能够获得更详细的错误消息提出建议。

亲切的问候,
弗洛里安

最佳答案

我必须编写自己的Spring Converter才能从“字符串”转换为“角色”,将该类标记为@Component并创建一个@Bean。然后它像魅力一样工作。

@Component
public class StringRoleConverter implements Converter<String, Role> {

    @Override
    public Role convert(String source) {
        Role role = new Role();
        int id = Integer.parseInt(source);
        role.setId(id);
        return role;
    }

    @Bean
    public ConversionService getConversionService() {
        ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean();
        Set<Converter> converters = new HashSet<>();
        converters.add(new StringRoleConverter());
        bean.setConverters(converters);
        return bean.getObject();
    }
}

关于java - Spring Thymeleaf如何将复选框的值绑定(bind)到集合字段,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38574933/

10-12 03:03