2016-04-05 14 views
1

İşlevler için standart javax.validation ve işlev doğrulamaları için kendi doğrulamamı kullanmak istiyorum.javax.validation (JSR303) bir temel sınıfta nasıl kullanılır?

public class TestData extends AbstractData { 
    @NotNull 
    Long id = null; 

    @NotNull 
    Long value = null; 

    public Set<ConstraintViolation<TestData>> validateFunctional() { 
    Set<ConstraintViolation<TestData>> violations = new HashSet<>(); 
    if (id < 42 || value > 4711) { 
     //--- here comes another question: how do I create a constraint violation? 
    } 
    return violations; 
    } 
} 

Bu temel sınıftır:: gibi basitleştirilmiş alt sınıf görünüyor

public abstract class AbstractData { 
    public Set<ConstraintViolation<?>> validate() { 
    //--- First validate single properties 
    Set<ConstraintViolation<?>> violations = validator.validate(this); 
    } 
    //--- Single props OK => validate functional 
    if (violations.isEmpty()) { 
    violations.add(validateFunctional()); 
    } 
    return violations; 
} 

hatayı

Tip uyuşmazlığı verir: Set ayarlama < ConstraintViolation <AbstractData> > gelen dönüştürülemiyor < ConstraintViolation <? >

+0

Derleyicinin, yaptığınız gibi jenerik türden çıkmasının bir yolu yoktur. – dambros

+0

Haklısınız. Derleyici, AbstractData'dan? 'A dönüşemez. Ama bu sözde-tip-güvenlikten nasıl kurtulabilirim? Bana öyle geliyor ki, Validator.validate arabirimi çok kötü tasarlanmış. Ya da sadece anlamadım ... –

cevap

0

> Ben Bu aradığınız ne olması gerektiğine inanıyoruz:

public abstract class AbstractData<T> { 

    abstract T getObj(); 

    public Set<ConstraintViolation<T>> isValid(){ 
    //do your custom validations if needed 
    return Validation.buildDefaultValidatorFactory() 
      .getValidator().validate(getObj()); 
    } 
} 

POJO doğrulanması:

public class Bar extends AbstractData<Bar> { 
    @NotNull 
    private Long id; 

    @NotNull 
    private Long value; 

    @CustomConstraint 
    private Long customConstraint; 

    @Override 
    public Bar getObj() { 
     return this; 
    } 
} 

Sonra basitçe bar.isValid() diyoruz.

DÜZENLEME: @CustomConstraint ile uzun bir alan açıklama ise, bu örnekte

@Constraint(validatedBy = {CustomConstraint.CustomConstraintValidator.class}) 
@Target({ElementType.FIELD, ElementType.PARAMETER}) 
@Retention(value = RetentionPolicy.RUNTIME) 
@Documented 
public @interface CustomConstraint { 

    String message() default "Invalid value"; 

    Class<?>[] groups() default {}; 

    Class<? extends Payload>[] payload() default {}; 

    class CustomConstraintValidator implements ConstraintValidator<CustomConstraint, Long> { 

     @Override 
     public void initialize(CustomConstraint customConstraint) { 

     } 

     @Override 
     public boolean isValid(Long obj, ConstraintValidatorContext constraintValidatorContext) { 
      if (obj == null) 
       return false; 

      if (obj < 10) 
       return false; 

      return true; 
     } 
    } 
} 

ve değer pass: Özel bir kısıtlama ilişkin sorunuza İlişkin

, bunu şöyle yapabiliriz 10'dan küçük veya null, doğrulayıcı bir hata döndürür, aksi takdirde olmaz. Doğrulamanın kendisi örnekte işe yaramıyor, ben sadece sizin için bir pasaj olarak hizmet etmek için bir şey koydum.

+0

İlginç bir yaklaşım. Fakat özel geçerlilikler alt sınıfta değil, alt sınıflardadır. Validator.validate'deki gerçekten garip genetiklerin üstesinden gelmek için, çözümünüz alt sınıfı kendi temel sınıfına jenerik bir parametre olarak vermektir, bu da "bu" değerini döndüren "soyut T getObj()" yöntemini gerektirir. Bu JSR'nin kullanılabilir olmasını sağlayan bir güncelleme almasını umuyorum. Özel bir geçerlilik denetçisi aramıyorum, ancak bunun yerine, bazı kodlar için, ihlal setine ekleyebileceğim bir kısıtlama ihlali oluşturabilmem için. –

+0

Sanırım burada bütün jenerikleri yanlış anlıyorsunuz, çünkü "validate()" tarafından nasıl uygulandığına dair yanlış bir şey göremiyorum. – dambros

+0

Yanlış değil. Hiçbir yararı olmadan sadece gereksiz yere karmaşık. Validate() için ilk paramater doğrulamak için fasulye. Yani sınıfı biliyor. Bu sahte tip güvenliğe ihtiyaç yoktur. Çözümünüz, buna uymak için temel sınıfa bir getçi eklemeyi önerdi. –

İlgili konular