spring - 如何正确地将复选框绑定(bind)到 thymeleaf 中的对象列表?

标签 spring spring-mvc thymeleaf

我的域模型由 Employee 组成和 Certificate .一名员工可以引用/拥有许多证书(一对多关系)。完整的证书列表可以从 certificateService 获得。 .

为我使用 th:checkbox 的员工分配一些特殊证书thymeleaf 中的元素如下:

<form action="#" th:action="@{/employee/add}" th:object="${employee}" method="post">
    <table>
        <tr>
            <td>Name</td>
            <td><input type="text" th:field="*{name}"></td>
        </tr>
        <tr>
            <td>Certificate</td>
            <td>
                <th:block th:each="certificate , stat : ${certificates}">
                    <input type="checkbox" th:field="*{certificates}" name="certificates" th:value="${certificate.id]}"/>
                    <label th:text="${certificate.name}" ></label>
                </th:block>
            </td>
        </tr>
        <tr>
            <td colspan="2"><input type="submit" value="Add"/></td>
        </tr>
    </table>
</form>

现在,当我尝试提交 HTML 表单时,我总是收到以下错误:

400 - The request sent by the client was syntactically incorrect.



我的问题是:如何使用 thymeleaf 正确地将复选框元素绑定(bind)到对象列表?

Controller
@RequestMapping(value = "/add" , method = RequestMethod.GET)
public String add(Model model) {
    model.addAttribute("employee",new Employee());
    model.addAttribute("certificates",certificateService.getList());
    return "add";
}

@RequestMapping(value = "/add" , method = RequestMethod.POST)
public String addSave(@ModelAttribute("employee")Employee employee) {
    System.out.println(employee);
    return "list";
}

员工实体
@Entity
@Table(name = "employee")
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    private int id;

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

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "emp_cert",
            joinColumns = {@JoinColumn(name = "employee_id")},
            inverseJoinColumns = {@JoinColumn(name = "certificate_id")})
    private List<Certificate> certificates;

    public Employee() {
        if (certificates == null)
            certificates = new ArrayList<>();
    }

    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 List<Certificate> getCertificates() {
        return certificates;
    }

    public void setCertificates(List<Certificate> certificates) {
        this.certificates = certificates;
    }

    @Override
    public String toString() {
        return "Employee [id=" + id + ", name=" + name + "certificates size = " + certificates.size() + " ]";
    }
}

证书实体
@Entity
@Table(name = "certificate")
public class Certificate {

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

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

    @ManyToMany(mappedBy = "certificates")
    private List<Employee> employees;

    public Certificate() {
        if (employees == null)
            employees = new ArrayList<>();
    }

    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 List<Employee> getEmployees() {
        return employees;
    }

    public void setEmployees(List<Employee> employees) {
        this.employees = employees;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + id;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Certificate other = (Certificate) obj;
        if (id != other.id)
            return false;
        return true;
    }
}

最佳答案

我使用自定义解决方案来解决这个问题,我通过发送 来实现它数组 证书 id 到 Controller 并以 的形式接收请求参数 .要求更改定义如下。

看法

         <tr>
             <td>Certificate</td>
             <td>
               <th:block th:each="certificate : ${certificates}">
                <input type="checkbox" name="cers" th:value="${certificate.id}"/>
                 <label th:text="${certificate.name}"></label>
               </th:block>
             </td>
           </tr>

Controller
@RequestMapping(value = "/add" , method = RequestMethod.POST)
public String addSave(
         @ModelAttribute("employee")Employee employee , 
         @RequestParam(value = "cers" , required = false) int[] cers ,
         BindingResult bindingResult , Model model) {

if(cers != null) {
    Certificate certificate = null ;
    for (int i = 0; i < cers.length; i++) {

        if(certificateService.isFound(cers[i])) {
            certificate = new  Certificate();
            certificate.setId(cers[i]);
          employee.getCertificates().add(certificate);  
        }
    }
        for (int i = 0; i < employee.getCertificates().size(); i++) {
            System.out.println(employee.getCertificates().get(i));
        }
}

关于spring - 如何正确地将复选框绑定(bind)到 thymeleaf 中的对象列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39424715/

相关文章:

java - Spring 文件上传的问题

java - 如何使用注解配置 Spring MVC

spring-boot - SpringBoot,Thymeleaf,Gradle:未访问静态资源,CSS未显示

java - 如何在 JDBC url 中访问 `classpath:` 的父级?

java - Spring - 在 Controller 中检查路径变量是否为空

java - 绑定(bind) Spring :checkboxes to enumset on submit causes error

spring - 如何在 Spring MVC-Spring Security 应用程序中处理 GWT RPC 调用的 session 过期异常

java - Spring项目模板不显示模板

java - 升级到 Spring Boot 2.2.2.RELEASE + Thymeleaf 3.0.11.RELEASE,thymeleaf/layout 停止工作

java - 左加入 spring data jpa 和 querydsl