JSR-303 @Valid annotation not working for list of child objects

安稳与你 提交于 2019-11-26 06:36:11

问题


My main classes is

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

A Controller

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

A JSP page

<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>

Why object fields are not validated AddressForm?

Please help.


回答1:


You need to decorate addresses member of UserAddressesForm with @Valid annotation. See section 3.1.3 and 3.5.1 of JSR 303: Bean Validation. As I explained in my answer to the question Is there a standard way to enable JSR 303 Bean Validation using annotated method, this is the real use of @Valid annotation as per JSR 303.

Edit Example code: Hibernate Validator- Object Graph. (The list of passengers in Car)




回答2:


Adding to @Ritesh answer, @Valid constraint will instruct the Bean Validator to delve to the type of its applied property and validate all constraints found there. Answer with code to your question, the validator, when seeing a @Valid constraint on addresses property, will explore the AddressForm class and validate all JSR 303 constraints found inside, as follows:

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



回答3:


In the class UserAddressesForm add the following lines

@Valid
private List<AddressForm> addresses;



回答4:


Working solution.

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


来源:https://stackoverflow.com/questions/5142065/jsr-303-valid-annotation-not-working-for-list-of-child-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!