2015-12-01 22 views
5
Ben

Bahar doğrulama

Bir Varlık: varlık için

package org.ibp.soq; 

public class MyEntity { 

    private String field1; 
    private String field2; 

    //..getters and setters 

} 

Validator:

package org.ibp.soq; 

import org.springframework.stereotype.Component; 
import org.springframework.validation.Errors; 
import org.springframework.validation.Validator; 

@Component 
public class MyEntityValidator implements Validator { 

    @Override 
    public boolean supports(Class<?> clazz) { 
     return MyEntity.class.equals(clazz); 
    } 

    @Override 
    public void validate(Object target, Errors errors) { 
     MyEntity myEntity = (MyEntity) target; 
     // Logic to validate my entity 
     System.out.print(myEntity); 
    } 

} 

ve

dökme PUT yöntemi ile dinlenme kontrol: Aşağıdaki istek gövde ile bu kaynak için bir satış isteğinde

package org.ibp.soq; 

import java.util.List; 

import javax.validation.Valid; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.web.bind.WebDataBinder; 
import org.springframework.web.bind.annotation.InitBinder; 
import org.springframework.web.bind.annotation.RequestBody; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RestController; 

@RestController 
@RequestMapping("/myEntity") 
public class MyEntityRestResource { 

    @Autowired 
    private MyEntityValidator myEntityValidator; 

    @InitBinder 
    protected void initBinder(final WebDataBinder binder) { 
     binder.addValidators(this.myEntityValidator); 
    } 

    @RequestMapping(method = RequestMethod.PUT) 
    public void bulkCreate(@RequestBody @Valid List<MyEntity> myEntities) { 
     // Logic to bulk create entities here. 
     System.out.print(myEntities); 
    } 
} 

:

[ 
    { 
    "field1": "AA", 
    "field2": "11" 
    }, 

    { 
    "field1": "BB", 
    "field2": "22" 
    } 
] 

I elde hatadır:

"Invalid target for Validator [[email protected]]: [[email protected], [email protected]]" 
MyEntityValidator vALIDA, tek MyEntity doğrulama "destekler" değil çünkü

bu olduğunu anlayabiliriz ArrayList<MyEntity> için. I istek gövdesinde tek MyEntity nesne ve @RequestBody @Valid MyEntity myEntity parametresi olan bir karşılık gelen kontrol cihazı yöntemi varsa

MyEntityValidator mükemmel çalışır.

nasıl kullanmış doğrulayıcı kurulumu, MyEntity 's toplama doğrulama desteklemek için uzatılabilir ?

cevap

1

Tahmin edebileceğiniz gibi bu bahar Doğrulama kullanılarak elde edilemez. Spring Validation, Object validation'ın aksine Bean Validation (JSR 303/349) uygular. Ne yazık ki bir koleksiyon bir Java Bean değildir. Sen yöntemini myEntityValidator. validate(targetObject, errors) oluşturmak için toplu olarak elle bir Java Bean

  • Çağrı içindeki doğrulayıcı listenizi sarın iki seçenek

    • var.
  • 10

    çözüm Collection için özel bir Validator yaratmaktır ve WebDataBinders o Validator kaydeder bir @ControllerAdvice.

    Doğrulayıcı:

    import java.util.Collection; 
    
    import org.springframework.validation.Errors; 
    import org.springframework.validation.ValidationUtils; 
    import org.springframework.validation.Validator; 
    import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; 
    
    /** 
    * Spring {@link Validator} that iterates over the elements of a 
    * {@link Collection} and run the validation process for each of them 
    * individually. 
    * 
    * @author DISID CORPORATION S.L. (www.disid.com) 
    */ 
    public class CollectionValidator implements Validator { 
    
        private final Validator validator; 
    
        public CollectionValidator(LocalValidatorFactoryBean validatorFactory) { 
        this.validator = validatorFactory; 
        } 
    
        @Override 
        public boolean supports(Class<?> clazz) { 
        return Collection.class.isAssignableFrom(clazz); 
        } 
    
        /** 
        * Validate each element inside the supplied {@link Collection}. 
        * 
        * The supplied errors instance is used to report the validation errors. 
        * 
        * @param target the collection that is to be validated 
        * @param errors contextual state about the validation process 
        */ 
        @Override 
        @SuppressWarnings("rawtypes") 
        public void validate(Object target, Errors errors) { 
        Collection collection = (Collection) target; 
        for (Object object : collection) { 
         ValidationUtils.invokeValidator(validator, object, errors); 
        } 
        } 
    } 
    

    ControllerAdvice:

    import org.springframework.beans.factory.annotation.Autowired; 
    import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; 
    import org.springframework.web.bind.WebDataBinder; 
    import org.springframework.web.bind.annotation.ControllerAdvice; 
    import org.springframework.web.bind.annotation.InitBinder; 
    
    /** 
    * Controller advice that adds the {@link CollectionValidator} to the 
    * {@link WebDataBinder}. 
    * 
    * @author DISID CORPORATION S.L. (www.disid.com) 
    */ 
    @ControllerAdvice 
    public class ValidatorAdvice { 
    
        @Autowired 
        protected LocalValidatorFactoryBean validator; 
    
    
        /** 
        * Adds the {@link CollectionValidator} to the supplied 
        * {@link WebDataBinder} 
        * 
        * @param binder web data binder. 
        */ 
        @InitBinder 
        public void initBinder(WebDataBinder binder) { 
        binder.addValidators(new CollectionValidator(validator)); 
        } 
    } 
    
    +0

    Teşekkürler! Bu yaklaşımı kesinlikle deneyeceğim. –

    +2

    Use \ @ControllerAdvice, tüm denetleyicilere CollectionValidator uygulayacaktır. Tahsilat olmayan bir nesne üzerinde başka bir @ @ Valid ek açıklama varsa "java.lang.IllegalStateException: Validator için geçersiz hedef" özelliğine neden olur. –

    +0

    Bunun yerine \ @ InitBinder ("attrName") kullanın veya initBinder'ı belirli bir denetleyicide yapın. –

    0

    Aslında, bu Spring Doğrulama ve JSR303 kullanılarak elde edilebilir.

    • Bir MethodValidationPostProcessor Bean'i ortaya çıkarın.
    • @Validated (org.springframework.validation.annotation ile kontrolör sınıfı açıklama.Doğrulanmış)
    • MyEntity alanlarınızdaki/yöntemlerinizdeki JSR303 doğrulama ek açıklamalarını kullanın.
    • @Valid ile RequestBody argümanını ekleyiniz (bunu daha önce bu örnekte yaptınız).
    • MethodArgumentNotValidException işlemek için bir @ExceptionHandler yöntemi ekleyin. Bu kontrolörde veya bir @ControllerAdvice sınıfında yapılabilir.