108

主なモデルクラスは次のとおりです。

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
}

私のコントローラーの1つのエンドポイント:

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

 // logic here 

}

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

クラスの現在を@Valid検証しないのはなぜですか?List<AddressForm> addressesUserAddressesForm

4

6 に答える 6

180

addressesのメンバーUserAddressesForm@Validアノテーションで飾る必要があります。JSR 303: BeanValidationのセクション3.1.3および3.5.1を参照してください。質問への回答で説明したように、注釈付きの方法を使用してJSR 303 Bean Validationを有効にする標準的な方法はありますか?これは、JSR303による注釈の実際の使用法@Validです。

サンプルコードの編集: Hibernate Validator-ObjectGraph。(車の乗客のリスト)

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 Validation 2.0 / JakartaBeanValidationの新機能もご覧ください。

于 2011-02-28T14:04:12.427 に答える
31

@Riteshの回答に加えて、@Valid制約はBean Validatorに、適用されたプロパティのタイプを調べ、そこで見つかったすべての制約を検証するように指示します。質問にコードで答えると、バリデーターは、プロパティの@Valid制約を確認すると、クラスaddressesを探索し、内部で見つかったすべての制約を次のように検証します。AddressFormJSR 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
于 2016-10-05T15:52:53.197 に答える
10

クラスUserAddressesFormに、次の行を追加します

@Valid
private List<AddressForm> addresses;
于 2019-02-16T21:59:40.287 に答える
6

実用的なソリューション。

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
于 2019-04-26T20:42:04.167 に答える
0

親クラスにすべての提案と注釈付きの子フィールドをwithで実装しました@Validが、それでも子エンティティは検証されていませんでした。

幸いなことに、これで解決され、問題は依存関係が原因でした。解決策として、以下の依存関係を使用しました

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

それ以外の

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
</dependency>
于 2021-11-24T19:20:22.880 に答える
0

私にとって、それは@NotNull子供の中にあり、@NotEmpty注釈ではありませんでした。私はそれを機能させるために告知の@NotNull前に置かなければなり@Validませんでした。

このような:

private List<@NotNull @Valid YourObject> yourObjects;
于 2022-03-02T14:06:12.467 に答える