java - Getting Spring 4 dependency injection working with RESTeasy 3 validator -


i have been running lot of trouble trying custom bean validation constraints leverage spring's dependency injection.

for example might define constraint:

@constraint(validatedby = { customconstraintvalidator.class }) @documented @target({ elementtype.method, elementtype.field, elementtype.constructor, elementtype.parameter }) @retention(retentionpolicy.runtime) public @interface customconstraint {     string message() default "custom.constraint.error";      class<?>[] groups() default {};      class<? extends payload>[] payload() default {}; } 

validator implementation

@component public class customconstraint implements constraintvalidator<customconstraint, string> {      @autowired     private somespringbean somespringbean;      @override     public void initialize(customconstraint constraintannotation) {     }      @override     public boolean isvalid(string value, constraintvalidatorcontext context) {          if (value != null) {             someobject storedvalue = somespringbean.find(value);                      return storedvalue != null;         }          return true;     }  } 

the standard way setup bean validation resteasy pull in: org.jboss.resteasy:resteasy-validator-provider-11:3.0.6.final

however when validation executed @ runtime, @autowired field null.

versions
spring: 4.0.4.release
resteasy: 3.0.6.final

i have found solution, not ideal yet work , evolve proper solution.

after reading through many stackoverflow questions , various web articles found hardly references getting spring , resteasy working validation. there plenty of references spring , bean validation, once resteasy introduced discussion disappears. clear other discussions spring provides validatorfactory implementation called localvalidatorfactorybean enabled spring dependency injection within validator implementations.

looking org.jboss.resteasy:resteasy-validator-provider-11:3.0.6.final found out setting @provider instance provides generalvalidator used resteasy resolve bean validation. problem noticed provider class, validatorcontextresolver, not provide way set different version of validatorfactory. tries load via cdi / jndi , if fails defaults hardcoded validatorfactory implementation. in instance can't rely on jndi lookup there no way provide spring's localvalidatorfactorybean factory.

on other hand resteasy-validator-provider-11 small library , code need change instead use spring's localvalidatorfactorybean minimal. can drop resteasy-validator-provider-11 dependency , reimplement library use spring instead. show related code below working, leaving out classes resteasy-validator-provider-11 library did not change.

validatorcontextresolver
you need copy of localvalidatorfactorybean bootstrapped spring, cannot instantiate new here:

@component @provider public class validatorcontextresolver implements contextresolver<generalvalidator> {     private final static logger log = logger.getlogger(validatorcontextresolver.class);     private volatile validatorfactory validatorfactory;     final static object rd_lock = new object();      @autowired     private validatorfactory springvalidatorfactorybean;      // used initialized in static block, having trouble class loading context resolver in     // environments. instead of failing , logging warning when resolver instantiated @ deploy time     // log validation warning when trying obtain validatorfactory.     validatorfactory getvalidatorfactory() {         validatorfactory tmpvalidatorfactory = validatorfactory;         if (tmpvalidatorfactory == null) {             synchronized (rd_lock) {                 tmpvalidatorfactory = validatorfactory;                 if (tmpvalidatorfactory == null) {                     log.info("obtaining spring-bean enabled validator factory");                     validatorfactory = tmpvalidatorfactory = springvalidatorfactorybean;                 }             }         }         return validatorfactory;     }      @override     public generalvalidator getcontext(class<?> type) {         try {             configuration<?> config = validation.bydefaultprovider().configure();             bootstrapconfiguration bootstrapconfiguration = config.getbootstrapconfiguration();             boolean isexecutablevalidationenabled = bootstrapconfiguration.isexecutablevalidationenabled();             set<executabletype> defaultvalidatedexecutabletypes = bootstrapconfiguration.getdefaultvalidatedexecutabletypes();             return new generalvalidatorimpl(getvalidatorfactory(), isexecutablevalidationenabled, defaultvalidatedexecutabletypes);         } catch (exception e) {             throw new validationexception("unable load validation support", e);         }     } } 

springvalidationconfig
setup localvalidatorfactorybean bean in spring. can want, prefer programmatically

@configuration public class databaseconfig {     @bean     public validatorfactory validator() {         localvalidatorfactorybean localvalidatorfactorybean = new localvalidatorfactorybean();        // localvalidatorfactorybean.setvalidationmessagesource(getvalidationmessagesource());         return localvalidatorfactorybean;     } } 

and configure spring load both of classes. component-scan in spring config like:

<context:component-scan base-package="org.example.resteasy.spring.validation.config" /> 

following these steps able @autowired dependency injection working in custom validation constraint implementations in question.

the ideal path forward have alternate resteasy-validator-provider-11 works spring.


Comments

Popular posts from this blog

php - render data via PDO::FETCH_FUNC vs loop -

c++ - OpenCV Error: Assertion failed <scn == 3 ::scn == 4> in unknown function, -

The canvas has been tainted by cross-origin data in chrome only -