2015-02-24 47 views
11

Bir POJO'nun alanlarındaki açıklamalı yay doğrulaması, json istek gövdesinden oluşturulduğunda çalışır. Ancak, aynı nesneyi el ile oluşturduğumda (setters kullanarak) ve doğrulamayı tetiklemek istediğimde, bunu nasıl yapacağımı bilmiyorum.Yay doğrulaması manuel olarak nasıl tetiklenir?

Nesneyi oluşturabilen Oluşturucu iç sınıfı olan Kayıt sınıfı İşte. Yapım yönteminde yaylı validasyonu tetiklemek istiyorum. Lütfen mevcut uygulamaya geçmek için aşağıya kaydırın ve Builder.build() ve Builder.valiate() yöntemlerini kontrol edin. Doğrulamayı tetiklemek için javax.validation.Validator kullanıyorum, ancak mümkünse yaylı doğrulamayı kaldırmayı tercih ediyorum.

package com.projcore.dao; 

import com.projcore.util.ToString; 
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 
import org.hibernate.validator.constraints.NotEmpty; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

import javax.validation.ConstraintViolation; 
import javax.validation.Valid; 
import javax.validation.Validation; 
import javax.validation.Validator; 
import javax.validation.constraints.Size; 
import java.util.List; 
import java.util.Set; 

/** 
* The data transfer object that contains the information of a Registration 
* and validation rules for attributes. 
*/ 
@JsonIgnoreProperties(ignoreUnknown = true) 
public final class Registration { 
    private static final Logger LOGGER = LoggerFactory.getLogger(Registration.class); 

    private String id; 

    @NotEmpty 
    @Size(max = 255) 
    private String messageId; 

    @NotEmpty 
    @Size(max = 255) 
    private String version; 

    @Size(max = 255) 
    private String system; 

    public Registration() { 
    } 

    private Registration(Builder builder) { 
     this.id = builder.id; 
     this.messageId = builder.messageId; 
     this.version = builder.version; 
     this.system = builder.system; 
    } 

    public static Builder getBuilder() { 
     return new Builder(); 
    } 

    public String getId() { 
     return id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 

    public String getMessageId() { 
     return messageId; 
    } 

    public void setMessageId(String messageId) { 
     this.messageId = messageId; 
    } 

    public String getVersion() { 
     return version; 
    } 

    public void setVersion(String version) { 
     this.version = version; 
    } 

    public String getSystem() { 
     return system; 
    } 

    public void setSystem(String system) { 
     this.system = system; 
    } 

    @Override 
    public String toString() { 
     return ToString.create(this); 
    } 

    /** 
    * Builder pattern makes the object easier to construct in one line. 
    */ 
    public static class Builder { 

     private String id; 

     private String messageId; 

     private String version; 

     private String system; 

     private Builder() {} 

     public Builder id(String id) { 
      this.id = id; 
      return this; 
     } 

     public Builder messageId(String messageId) { 
      this.messageId = messageId; 
      return this; 
     } 


     public Builder version(String version) { 
      this.version = version; 
      return this; 
     } 

     public Builder system(String system) { 
      this.system = system; 
      return this; 
     } 

     public Registration build() { 
      Registration entry = new Registration(this); 

      // *** Would like to trigger spring validation here *** 
      Set violations = validate(entry); 
      if (violations.isEmpty()) 
       return entry; 
      else 
       throw new RuntimeException(violations.toString()); 
     } 

     private Set validate(Registration entry) { 
      Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); 
      Set<ConstraintViolation<Registration>> constraintViolations = validator.validate(entry); 
      return constraintViolations; 
     } 

    } 
} 

Doğrulama ince burada çalışır:

@RequestMapping(method = RequestMethod.POST) 
@ResponseStatus(HttpStatus.CREATED) 
Registration create(@RequestBody @Valid Registration registration) 

Çözüm:

Registraion.Builder.validate kaldırıldı(). Güncel Registraion.Builder.build() için:

public Registration build() { 
     Registration entry = new Registration(this); 
     return (Registration) ValidatorUtil.validate(entry); 
    } 

ValidationUtil.java

package projcore.util; 

import com.ericsson.admcore.error.InvalidDataException; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.stereotype.Service; 
import org.springframework.validation.BeanPropertyBindingResult; 
import org.springframework.validation.Errors; 
import org.springframework.validation.beanvalidation.SpringValidatorAdapter; 

import javax.validation.Validation; 
import javax.validation.Validator; 
import java.util.Set; 

public class ValidatorUtil { 
    private static final Logger LOGGER = LoggerFactory.getLogger(ValidatorUtil.class); 
    private static final Validator javaxValidator = Validation.buildDefaultValidatorFactory().getValidator(); 
    private static final SpringValidatorAdapter validator = new SpringValidatorAdapter(javaxValidator); 

    public static Object validate(Object entry) { 
     Errors errors = new BeanPropertyBindingResult(entry, entry.getClass().getName()); 
     validator.validate(entry, errors); 
     if (errors == null || errors.getAllErrors().isEmpty()) 
      return entry; 
     else { 
      LOGGER.error(errors.toString()); 
      throw new InvalidDataException(errors.getAllErrors().toString(), errors); 
     } 
    } 
} 

InvalidDataException.java

package projcore.error; 

import org.springframework.validation.Errors; 

/** 
* This exception is thrown when the dao has invalid data. 
*/ 
public class InvalidDataException extends RuntimeException { 
    private Errors errors; 

    public InvalidDataException(String msg, Errors errors) { 
     super(msg); 
     setErrors(errors); 
    } 

    public Errors getErrors() { 
     return errors; 
    } 

    public void setErrors(Errors errors) { 
     this.errors = errors; 
    } 
} 

cevap

14

Yay JSR-303 fasulye Doğrulama API tam destek sağlar. Bu, bir Spring Bean olarak bir JSR-303 uygulamasının önyüklenmesi için uygun desteği içerir. Bu, uygulamanızda doğrulama gerekli olduğunda bir javax.validation.Validator'a enjekte edilmesine izin verir.

kullanımlar LocalValidatorFactoryBean Spring fasulyesi gibi bir varsayılan JSR-303 Doğrulayıcı yapılandırma:

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" /> 

temel yapısı yukarıda JSR-303, varsayılan önyükleme mekanizması kullanarak başlatmak için tetikler. Hibernate Validator gibi bir JSR-303 sağlayıcısının sınıf yolunda bulunması ve otomatik olarak algılanması beklenir.

5.7.2.1 Sen doğrulama mantığını çağırmak gerekir fasulye içine bu iki arayüz birine bir başvuru enjekte edebilir bir Validator

LocalValidatorFactoryBean implements both javax.validation.Validator and org.springframework.validation.Validator. enjekte ediliyor.

doğrudan JSR-303 API ile çalışmayı tercih eğer javax.validation.Validator bir başvuru enjekte:

// Spring Validator 
import org.springframework.validation.Validator; 

@Service 
public class MyService { 

    @Autowired 
    private Validator validator; 

} 

: Fasulye Bahar Doğrulama API gerektiriyorsa

// JSR-303 Validator 
import javax.validation.Validator; 

@Service 
public class MyService { 

    @Autowired 
    private Validator validator; 

} 

org.springframework.validation.Validator bir başvuru enjekte İşte iyi açıklanmış bir örnek Using JSR 303 with "classic" Spring Validators (enter the SpringValidatorAdapter)

Bu bağlantı çok faydalıdır. org.springframework.validation.beanvalidation.SpringValidatorAdapter 'daki javax.validation.Validator, hataların tutarlı bir şekilde ele alınmasına yardımcı oldu.Eğer cevap olarak bu ekleyebilir böylece ı kabul edebileceğini o

ve Spring doc here

+2

I (kendin yap zor değil) Bahar Boot de sizin için Validator fasulye sağladığını düşünüyorum. –

+1

Bu, bahar validator'un doğrulama işlemini tetiklemek için yalnızca bir @Service sınıfında kullanılabileceği anlamına mı geliyor? Online olarak yeterince okumuştum, bunun gibi örnekleri gördüm, ama yine de POJO içinde nasıl yapabileceğimi anlamıyorum, dolayısıyla soru. Ayrıca, özel doğrulayıcı için doğrulama işlemini nasıl tetikleyeceğini biliyorum, ancak POJO'da varsayılan doğrulamayı nasıl tetikleyeceğimi bilmiyorum. Mümkünse, sahip olduğum bağlam içerisinde belirli bir cevap verebilir misiniz? –

+1

Doğrulayıcıyı herhangi bir baharlık fasulyeye enjekte edebilirsiniz. Burada eski bir örnek var http://nonrepeatable.blogspot.com/2010/04/using-jsr-303-with-classic-spring.html. hala endişeleriniz varsa burada yorum – iamiddy

İlgili konular