4

是否可以同時擁有表單和註釋限制的驗證器?Spring驗證器:同時實現註釋和驗證器

例如,在表格對象爲具有該字段:

@NotEmpty 
private String date; 

但隨後驗證該日期的圖案在一個驗證。

我知道有模式註釋,但我只想看看我是否可以使用兩種類型的驗證。

回答

3

Here是鏈接到一個很好的網站,它解釋瞭如何與彈簧驗證結合JSR-303的驗證。

我將介紹下我的解決方案。希望能幫助到你。

我的抽象驗證:

import java.util.Map; 
import java.util.Set; 

import javax.validation.ConstraintValidator; 
import javax.validation.ConstraintValidatorFactory; 
import javax.validation.ConstraintViolation; 
import javax.validation.Validator; 

import org.springframework.beans.BeansException; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.ApplicationContext; 
import org.springframework.context.ApplicationContextAware; 
import org.springframework.validation.Errors; 


public abstract class AbstractValidator implements org.springframework.validation.Validator, ApplicationContextAware, 
    ConstraintValidatorFactory { 

@Autowired 
private Validator validator; 

private ApplicationContext applicationContext; 

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 
    this.applicationContext = applicationContext; 
} 

public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) { 
    Map<String, T> beansByNames = applicationContext.getBeansOfType(key); 
    if (beansByNames.isEmpty()) { 
     try { 
      return key.newInstance(); 
     } catch (InstantiationException e) { 
      throw new RuntimeException("Could not instantiate constraint validator class '" + key.getName() + "'", e); 
     } catch (IllegalAccessException e) { 
      throw new RuntimeException("Could not instantiate constraint validator class '" + key.getName() + "'", e); 
     } 
    } 
    if (beansByNames.size() > 1) { 
     throw new RuntimeException("Only one bean of type '" + key.getName() + "' is allowed in the application context"); 
    } 
    return (T) beansByNames.values().iterator().next(); 
} 

public boolean supports(Class<?> c) { 
    return true; 
} 

public void validate(Object objectForm, Errors errors) { 
    Set<ConstraintViolation<Object>> constraintViolations = validator.validate(objectForm); 
    for (ConstraintViolation<Object> constraintViolation : constraintViolations) { 
     String propertyPath = constraintViolation.getPropertyPath().toString(); 
     String message = constraintViolation.getMessage(); 
     errors.rejectValue(propertyPath, "", message); 
    } 
    addExtraValidation(objectForm, errors); 
} 

protected abstract void addExtraValidation(Object objectForm, Errors errors); 

}

實際的驗證:

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

import ro.scorpionsoftware.demo3.dao.AbstractValidator; 


@Component(value="doctorValidator") 
public class DoctorValidator extends AbstractValidator { 

    @Override 
    protected void addExtraValidation(Object objectForm, Errors errors) { 
     //perform typical validation 
     //can autowire to context 
    } 


} 

的控制器:(在結束它的所述@Valid與驗證結合)

@Controller 
public class DoctorEditController { 

@Autowired 
    private DoctorValidator doctorValidator; 

@RequestMapping(value = "/doctorEdit", method = RequestMethod.POST) 
    public String processSubmit(
      @ModelAttribute("doctorForm") @Valid DoctorForm df, 
      BindingResult result, 
      ModelMap model) { 
    ... 
} 
@InitBinder 
    protected void initBinder(WebDataBinder binder) { 
     binder.setValidator(doctorValidator); 
    } 
} 

在上下文聲明JSR-303驗證:

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

通過這種方法,你可以得到上下文中都實際驗證,你想實現的任何其他自定義註釋。

0

你可以將註釋組合在一起使用多個驗證器,所以它會是這樣的。

@NotEmpty 
@Pattern("") // not sure of syntax here 
@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME) 
@Constraint(validatedBy = {}) 
@Documented 
public @interface DatePattern { 
    String message() default ""; 

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

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