@Valid注释无法验证子对象的列表 [英] @Valid annotation is not validating the list of child objects

查看:75
本文介绍了@Valid注释无法验证子对象的列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

主要模型类如下:

 公共类UserAddressesForm {@不是空的私有字符串firstName;@不是空的私有字符串lastName;私人List< AddressForm>地址;//setter和getters} 


 公共类AddressForm {@不是空的私有字符串customName;@不是空的私人弦城市;@不是空的私人弦街@不是空的私人String streetHn;@不是空的私有字符串addressCountry;@不是空的私有String postCode;//setter和getters} 

我的一个控制器中的端点:

  @RequestMapping(值="/up",方法= RequestMethod.POST)public String completeForm(@Valid @ModelAttribute("userAddressesForm"))UserAddressesForm userAddressesForm,BindingResult结果,HttpServletRequest req){//这里的逻辑} 

.jsp 页面:

 < form:form commandName =" userAddressesForm"action =已注册">< table>< tr>< td class ="formLabels"> form:label path ="firstName">< spring:消息代码="label.name"/></form:label></td>< td>< form:input path ="firstName"/></td>< td>< form:errors path ="firstName"cssClass =错误";/></td></tr>< tr>< td class ="formLabels"> form:label path ="lastName">< spring:消息代码="label.surname"/></form:label></td>< td>< form:输入路径=姓氏"/></td>< td>< form:errors path ="lastName"cssClass =错误";/></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:消息代码="label.address.custom.name"/></td>< td>< spring:bind path =" addresss [$ {gridRow.index}].customName"><输入类型=输入"名称=< c:out值=" $ {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:消息代码="label.streetAnStreetHn";/></td>< td>< spring:bind path =" addresss [$ {gridRow.index}].streetAn"<输入类型=输入"名称=< c:out值=" $ {status.expression}"/".id =< c:out value =" $ {status.expression}"/";value =< c:out value =" $ {status.value}"/";/></spring:bind>< spring:bind path =" addresss [$ {gridRow.index}].streetHn"<输入类型=输入"名称=< c:out值=" $ {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 =" addresss [$ {gridRow.index}].postCode"><输入类型=输入"名称=< c:out值=" $ {status.expression}"/".id =< c:out value =" $ {status.expression}"/";value =< c:out value =" $ {status.value}"/";/></spring:bind></td></tr>< tr>< td class ="formLabels">< spring:消息代码="label.city"/></td>< td>< spring:bind path =" addresss [$ {gridRow.index}].city"<输入类型=输入"名称=< c:out值=" $ {status.expression}"/".id =< c:out value =" $ {status.expression}"/";value =< c:out value =" $ {status.value}"/";/>< form:errors path =" addresss [$ {gridRow.index}].city"cssClass =错误";/></spring:bind></td></tr></table></fieldset></div></c:forEach> 

为什么 @Valid 无法验证 List< AddressForm> UserAddressesForm 类中存在的地址吗?

解决方案

您需要使用 @Valid 批注装饰 UserAddressesForm addresses 成员.请参见 JSR 303:Bean验证的3.1.3和3.5.1节.正如我在对问题休眠验证器对象图.(汽车上的乘客列表)

编辑来自 Bean Validation 2.0/Jakarta Bean Validation ..>

Main model classes are as follows :

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
}

An endpoint in one of my controllers :

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

 // logic here 

}

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 @Valid is not validating the List<AddressForm> addresses present in UserAddressesForm class ?

解决方案

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)

Edit From Hibernate Validator 6 Reference doc:

In versions prior to 6, Hibernate Validator supported cascaded validation for a subset of container elements and it was implemented at the container level (e.g. you would use @Valid private List<Person> to enable cascaded validation for Person).

This is still supported but is not recommended. Please use container element level @Valid annotations instead as it is more expressive.

Example:

public class Car {

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

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

       //...
   }

Also see what's new in Bean Validation 2.0/Jakarta Bean Validation.

这篇关于@Valid注释无法验证子对象的列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆