JSR-303 @ คำอธิบายประกอบที่ถูกต้องไม่ทำงานสำหรับรายการวัตถุลูก


96

ชั้นเรียนหลักของฉันคือ

public class UserAddressesForm {

    @NotEmpty
    private String firstName;

    @NotEmpty
    private String lastName;

    private List<AddressForm> addresses;

...
setters and getters 

public class AddressForm {

    @NotEmpty
    private String customName;
    @NotEmpty
    private String city;
    @NotEmpty
    private String streetAn;
    @NotEmpty
    private String streetHn;
    @NotEmpty
    private String addressCountry;
    @NotEmpty
    private String postCode;
...
setters and getters

ตัวควบคุม

@RequestMapping(value = "/up", method = RequestMethod.POST)
    public String completeForm(@Valid @ModelAttribute("userAddressesForm") UserAddressesForm userAddressesForm,  
            BindingResult result, HttpServletRequest req)
...

หน้า JSP

<form:form commandName="userAddressesForm" action="registered">
    <table>

        <tr>
            <td class="formLabels"><form:label path="firstName">
                <spring:message code="label.name" />
            </form:label></td>
            <td><form:input path="firstName" /></td>
            <td><form:errors path="firstName" cssClass="error" /></td>
        </tr>
        <tr>
            <td class="formLabels"><form:label path="lastName">
                <spring:message code="label.surname" />
            </form:label></td>
            <td><form:input path="lastName" /></td>
            <td><form:errors path="lastName" cssClass="error" /></td>
        </tr>
    </table>

    <c:forEach items="${userAddressesForm.addresses}" varStatus="gridRow">  
        <div id="main_address" class="address_data_form">
            <fieldset>
                <legend><spring:message code="label.stepThreeMainAddressInfo" /></legend>
                <a href="#" class="deleteItem"></a>
                <table>
                    <tr>            
                        <td class="formLabels">
                            <spring:message code="label.address.custom.name" />
                        </td>
                        <td>
                            <spring:bind path="addresses[${gridRow.index}].customName">
                                <input type="input" name="<c:out value="${status.expression}"/>"
                                    id="<c:out value="${status.expression}"/>"
                                    value="<c:out value="${status.value}"/>" />
                                    <form:errors path="${status.expression}"/>
                            </spring:bind>
                        </td>   
                    </tr>               
                    <tr>            
                        <td class="formLabels">
                            <spring:message code="label.streetAnStreetHn" />
                        </td>
                        <td>
                            <spring:bind path="addresses[${gridRow.index}].streetAn">
                                <input type="input" name="<c:out value="${status.expression}"/>"
                                    id="<c:out value="${status.expression}"/>"
                                    value="<c:out value="${status.value}"/>" />
                            </spring:bind>
                            <spring:bind path="addresses[${gridRow.index}].streetHn">
                            <input type="input" name="<c:out value="${status.expression}"/>"
                                id="<c:out value="${status.expression}"/>"
                                value="<c:out value="${status.value}"/>" >
                            <form:errors path="addresses[${gridRow.index}].streetHn"/>
                            </spring:bind>

                        </td>
                    </tr>
                    <tr>                        
                        <td class="formLabels">
                            <spring:message code="label.postCode" />
                        </td>
                        <td>
                            <spring:bind path="addresses[${gridRow.index}].postCode">
                                <input type="input" name="<c:out value="${status.expression}"/>"
                                    id="<c:out value="${status.expression}"/>"
                                    value="<c:out value="${status.value}"/>" />
                            </spring:bind>
                        </td>                   
                    </tr>
                    <tr>                
                        <td class="formLabels">
                            <spring:message code="label.city" />
                        </td>
                        <td>
                            <spring:bind path="addresses[${gridRow.index}].city">
                                <input type="input" name="<c:out value="${status.expression}"/>"
                                    id="<c:out value="${status.expression}"/>"
                                    value="<c:out value="${status.value}"/>" />
                                <form:errors path="addresses[${gridRow.index}].city" cssClass="error" />
                            </spring:bind>
                        </td>
                    </tr>       
                </table>    
            </fieldset>
        </div>
    </c:forEach>

เหตุใดช่องวัตถุจึงไม่ได้รับการตรวจสอบ AddressForm

กรุณาช่วย.

คำตอบ:


168

คุณต้องตกแต่งaddressesสมาชิกUserAddressesFormด้วย@Validคำอธิบายประกอบ โปรดดูที่ส่วน 3.1.3 และ 3.5.1 ของJSR 303: Bean ตรวจสอบ ดังที่ฉันได้อธิบายไว้ในคำตอบสำหรับคำถามมีวิธีมาตรฐานในการเปิดใช้งาน JSR 303 Bean Validation โดยใช้วิธีการใส่คำอธิบายประกอบหรือไม่นี่คือการใช้@Validคำอธิบายประกอบตาม JSR 303 จริง

แก้ไข รหัสตัวอย่าง: Hibernate Validator- กราฟวัตถุ (รายชื่อผู้โดยสารในรถ)

แก้ไขจากHibernate Validator 6เอกสารอ้างอิง:

ในเวอร์ชันก่อนหน้า 6 Hibernate Validator รองรับการตรวจสอบแบบเรียงซ้อนสำหรับส่วนย่อยขององค์ประกอบคอนเทนเนอร์และถูกนำไปใช้ในระดับคอนเทนเนอร์ (เช่นคุณจะใช้@Valid private List<Person>เพื่อเปิดใช้งานการตรวจสอบแบบเรียงซ้อนสำหรับPerson)

สิ่งนี้ยังคงรองรับ แต่ไม่แนะนำ โปรดใช้@Validคำอธิบายประกอบระดับองค์ประกอบคอนเทนเนอร์แทนเนื่องจากมีความชัดเจนมากขึ้น

ตัวอย่าง:

public class Car {

        private List<@NotNull @Valid Person> passengers = new ArrayList<Person>();

        private Map<@Valid Part, List<@Valid Manufacturer>> partManufacturers = new HashMap<>();

       //...
   }

นอกจากนี้ยังเห็นว่ามีอะไรใหม่ในBean การตรวจสอบ 2.0 / จาการ์ตา Bean ตรวจสอบ


1
แล้วการจัดกลุ่มล่ะ? ฉันต้องการให้ที่อยู่ได้รับการตรวจสอบเมื่อตรวจสอบความถูกต้องของกลุ่ม A แล้วเท่านั้น @Validละเว้นกลุ่ม
Akshay

1
@Validคำอธิบายประกอบ@Akshay ทำงานที่ระดับล่าง ฉันคิดว่า@GroupSequenceสามารถใช้เพื่อระบุลำดับการตรวจสอบความถูกต้องได้
พิธี

รายละเอียดคำถามของฉันstackoverflow.com/q/41457404/1534925 อย่าคิดว่าลำดับจะใช้ได้ในกรณีของฉัน
Akshay

27

การเพิ่มคำตอบ @Ritesh @Validข้อ จำกัด จะสั่งให้ Bean Validator เจาะลึกถึงประเภทของคุณสมบัติที่ใช้และตรวจสอบข้อ จำกัด ทั้งหมดที่พบในนั้น ตอบด้วยรหัสสำหรับคำถามของคุณผู้ตรวจสอบเมื่อเห็น@Validข้อ จำกัด เกี่ยวกับaddressesคุณสมบัติจะสำรวจAddressFormชั้นเรียนและตรวจสอบJSR 303ข้อ จำกัดทั้งหมดที่พบภายในดังนี้:

public class UserAddressesForm {

    @NotEmpty
    private String firstName;

    @NotEmpty
    private String lastName;

    @Valid
    private List<AddressForm> addresses;

...
setters and getters 

public class AddressForm {

    @NotEmpty
    private String customName;
    @NotEmpty
    private String city;
    @NotEmpty
    private String streetAn;
    @NotEmpty
    private String streetHn;
    @NotEmpty
    private String addressCountry;
    @NotEmpty
    private String postCode;
...
setters and getters

1
แล้วการจัดกลุ่มล่ะ? ฉันต้องการให้ที่อยู่ได้รับการตรวจสอบเมื่อตรวจสอบความถูกต้องของกลุ่ม A แล้วเท่านั้น @Valid ละเว้นกลุ่ม
Akshay

ฉันไม่ได้อ่านคำตอบของคุณ แต่เพียงแค่ดูที่การsetters and gettersแก้ไขปัญหาของฉัน
Shubham Khandare


5

โซลูชันการทำงาน

public class UserAddressesForm {

    @NotEmpty(message="firstName is required")
    private String firstName;

    @NotEmpty(message="lastNameis required")
    private String lastName;

    @NotNull(message="addresses attributes are required")
    @Valid
    private List<AddressForm> addresses;

...
setters and getters 

public class AddressForm {

    @NotEmpty(message="customNameis required")
    private String customName;
    @NotEmpty
    private String city;
    @NotEmpty
    private String streetAn;
    @NotEmpty
    private String streetHn;
    @NotEmpty
    private String addressCountry;
    @NotEmpty
    private String postCode;
...
setters and getters
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.