Spring中使用Thymeleaf的绑定列表。错误:对象验证失败

时间:2019-06-06 07:41:09

标签: spring spring-boot spring-mvc thymeleaf

在post方法中,它返回错误:对象验证失败。

一些信息:事件包含1个或大多数展览。

我的ExhibitList类

public class ExhibitList {

    private List<Exhibit> exhibits;

    public List<Exhibit> getExhibits() {
        return exhibits;
    }

    public void setExhibits(List<Exhibit> exhibits) {
        this.exhibits = exhibits;
    }

    public void addExhibit(Exhibit exhibit) {
        this.exhibits.add(exhibit);
    }
}

我的事件控制器

@RequestMapping(value = "")
    public String incidentRegister(Model model, Principal principal, @PathParam("id") Long id) {


            Incident incident = new Incident();
            model.addAttribute("incident", incident);

            ExhibitList exhibitList = new ExhibitList();
            model.addAttribute("exhibitList", exhibitList);

        return "incidentRegister";
    }

    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public String incidentRegisterPost(@ModelAttribute("exhibitList") ExhibitList exhibitList,
            @ModelAttribute("incident") Incident incident, @ModelAttribute("exhibit") Exhibit exhibit) throws Exception {


        System.out.println("Size: " + exhibitList.getExhibits().size());
        for (Exhibit exhibit2 : exhibitList.getExhibits()) {
            System.out.println("Description: " + exhibit2.getExhibitDescription());
            System.out.println("Marking: " + exhibit2.getExhibitMarking());
            System.out.println("Remarks: " + exhibit2.getExhibitRemarks());
        }

        return "incidentDetail";
    }

我的观点

<div class="container main">
    <form th:action="@{/incidentRegister/register}" method="post"
        id="formIncidentRegister" onsubmit="return confirm('Are you sure you want to register this Incident?')">

<h3>Exhibit Details</h3>

        <div id="exhibitList">
            <div class="form-row item"
                th:each="exhibit, status : ${exhibitList.exhibits}">
                <div class="form-group col-md-4">
                    <label for="location">Description</label> <input
                        th:field="*{exhibits[__${status.index}__].exhibitDescription}"
                        type="text" class="form-control" />
                </div>

                <div class="form-group col-md-4">
                    <label for="location">Marking</label> <input
                        th:field="*{exhibits[__${status.index}__].exhibitMarking}"
                        type="text" class="form-control" />
                </div>

                <div class="form-group col-md-4">
                    <label for="location">Remarks</label> <input
                        th:field="*{exhibits[__${status.index}__].exhibitRemarks}"
                        type="text" class="form-control" />

                </div>
            </div>
        </div>

        <div class="form-row">
            <div class="col">
                <button type="button" class="btn btn-primary" onclick="addRow()">Add
                    Exhibit</button>
            </div>
        </div>

</form>
</div>


<script type="text/javascript">
    let addRow = function() {

        let listName = 'exhibits';
        let fieldsNames = [ 'exhibitDescription', 'exhibitMarking',
                'exhibitRemarks' ];
        let rowIndex = document.querySelectorAll('.item').length;

        let row = document.createElement('div');
        row.classList.add('form-row', 'item');

        fieldsNames.forEach((fieldName) => {

            let col = document.createElement('div');
            col.classList.add('form-group', 'col-md-4');

            let label = document.createElement('label');
            if(fieldName === 'exhibitDescription'){
                label.innerHTML = 'Description';
            } else if(fieldName === 'exhibitMarking'){
                label.innerHTML = 'Marking';
            } else{
                label.innerHTML = 'Remarks';
            }

            let input = document.createElement('input');
            input.type = 'text';
            input.classList.add('form-control');
            input.setAttribute('name', listName + '[' + rowIndex + ']' + fieldName);

            col.appendChild(label);
            col.appendChild(input);
            row.appendChild(col);
        });
        document.getElementById('exhibitList').appendChild(row);
    };
    //<![CDATA[
    $(document).ready(function() {

    });
    //]]>
</script>

它返回错误“对象验证失败” =“ exhibitList”。错误计数:3'。我该如何从列表中获取展览品的价值。

谢谢。

更新1

我的控制器

@RequestMapping(value = "")
    public String incidentRegister(Model model, Principal principal, @PathParam("id") Long id) {

...

List<Exhibit> exhibitList = new ArrayList<>();
            ExhibitsCreationDto exhibitForm = new ExhibitsCreationDto(exhibitList);
            exhibitForm.addExhibit(new Exhibit());

            model.addAttribute("form", exhibitForm);
}

我的视图

<form th:action="@{/incidentRegister/register}" method="post"
        th:object="${form}" id="formIncidentRegister"
        onsubmit="return confirm('Are you sure you want to register this Incident?')">

<h3>Exhibit Details</h3>

        <div id="exhibitList">
            <div class="form-row item"
                th:each="exhibit, status : ${form.exhibits}">

                <div class="form-group col-md-4">
                    <label for="location">Description</label> <input
                        th:field="*{exhibits[__${status.index}__].exhibitDescription}"
                        type="text" class="form-control" required="required"/>
                </div>

                <div class="form-group col-md-4">
                    <label for="location">Marking</label> <input
                        th:field="*{exhibits[__${status.index}__].exhibitMarking}"
                        type="text" class="form-control" required="required"/>
                </div>

                <div class="form-group col-md-4">
                    <label for="location">Remarks</label> <input
                        th:field="*{exhibits[__${status.index}__].exhibitRemarks}"
                        type="text" class="form-control" required="required"/>

                </div>
            </div>
        </div>

        <div class="form-row">
            <div class="col">
                <button type="button" class="btn btn-primary" onclick="addRow()">Add
                    Exhibit</button>
            </div>
        </div>

        <p></p>

        <div class="form-group ">
            <button type="submit"
                class="btn btn-primary btn-lg btn-block login-button">Register</button>
        </div>

        <hr />

        <div class="form-group ">
            <a class="btn btn-info btn-lg btn-block login-button"
                th:href="@{/incidentQuery}">Cancel</a>
        </div>

</form>

<script type="text/javascript">

...

    let addRow = function() {

        let listName = 'exhibits';
        let fieldsNames = [ 'exhibitDescription', 'exhibitMarking',
                'exhibitRemarks' ];
        let rowIndex = document.querySelectorAll('.item').length;

        let row = document.createElement('div');
        row.classList.add('form-row', 'item');

        fieldsNames.forEach((fieldName) => {

            let col = document.createElement('div');
            col.classList.add('form-group', 'col-md-4');

            let label = document.createElement('label');
            if(fieldName === 'exhibitDescription'){
                label.innerHTML = 'Description';
            } else if(fieldName === 'exhibitMarking'){
                label.innerHTML = 'Marking';
            } else{
                label.innerHTML = 'Remarks';
            }

            let input = document.createElement('input');
            input.type = 'text';
            input.classList.add('form-control');
            input.id = listName + rowIndex + '.' + fieldName;
            input.setAttribute('name', listName + '[' + rowIndex + ']' + fieldName);

            col.appendChild(label);
            col.appendChild(input);
            row.appendChild(col);
        });
        document.getElementById('exhibitList').appendChild(row);
    };
</script>

1 个答案:

答案 0 :(得分:1)

在表单标签中添加th:object="${exhibitList}"并像这样修改控制器,因为您的类中没有任何构造函数。因此,当您初始化ExhibitList类时,其所有属性以及列表也都为null。而且您无法获得空列表的索引。

ExhibitList exhibitList = new ExhibitList();

List<Exhibit> itemList= new ArrayList<>();
exhibitList.setsetExhibits(itemList);
model.addAttribute("exhibitList", exhibitList);



  @RequestMapping(value = "/register", method = RequestMethod.POST)


       public String incidentRegisterPost(@ModelAttribute("exhibitList") ExhibitList exhibitList,BindingResult bindingResult) throws Exception {



            System.out.println("Size: " + exhibitList.getExhibits().size());
          // others

            return "incidentDetail";
    }
相关问题