11/*
2- * Copyright 2002-2012 the original author or authors.
2+ * Copyright 2002-2013 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
3030import javax .validation .ConstraintValidator ;
3131import javax .validation .ConstraintValidatorContext ;
3232import javax .validation .ConstraintViolation ;
33+ import javax .validation .Payload ;
3334import javax .validation .Valid ;
3435import javax .validation .constraints .NotNull ;
3536
3637import org .hibernate .validator .HibernateValidator ;
3738import org .junit .Test ;
3839
3940import org .springframework .validation .BeanPropertyBindingResult ;
41+ import org .springframework .validation .Errors ;
4042import org .springframework .validation .FieldError ;
4143import org .springframework .validation .ObjectError ;
4244
@@ -193,6 +195,18 @@ public void testSpringValidationWithErrorInSetElement() throws Exception {
193195 System .out .println (fieldError .getDefaultMessage ());
194196 }
195197
198+ @ Test
199+ public void testInnerBeanValidation () throws Exception {
200+ LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean ();
201+ validator .afterPropertiesSet ();
202+
203+ MainBean mainBean = new MainBean ();
204+ Errors errors = new BeanPropertyBindingResult (mainBean , "mainBean" );
205+ validator .validate (mainBean , errors );
206+ Object rejected = errors .getFieldValue ("inner.value" );
207+ assertNull (rejected );
208+ }
209+
196210
197211 @ NameAddressValid
198212 public static class ValidPerson {
@@ -242,7 +256,6 @@ public void setAddressSet(Set<ValidAddress> addressSet) {
242256 }
243257 }
244258
245-
246259 public static class ValidAddress {
247260
248261 @ NotNull
@@ -257,7 +270,6 @@ public void setStreet(String street) {
257270 }
258271 }
259272
260-
261273 @ Target (ElementType .TYPE )
262274 @ Retention (RetentionPolicy .RUNTIME )
263275 @ Constraint (validatedBy = NameAddressValidator .class )
@@ -270,7 +282,6 @@ public void setStreet(String street) {
270282 Class <?>[] payload () default {};
271283 }
272284
273-
274285 public static class NameAddressValidator implements ConstraintValidator <NameAddressValid , ValidPerson > {
275286
276287 @ Override
@@ -283,4 +294,53 @@ public boolean isValid(ValidPerson value, ConstraintValidatorContext constraintV
283294 }
284295 }
285296
297+
298+ public static class MainBean {
299+
300+ @ InnerValid
301+ private InnerBean inner = new InnerBean ();
302+
303+ public InnerBean getInner () {
304+ return inner ;
305+ }
306+ }
307+
308+ public static class InnerBean {
309+
310+ private String value ;
311+
312+ public String getValue () {
313+ return value ;
314+ }
315+ public void setValue (String value ) {
316+ this .value = value ;
317+ }
318+ }
319+
320+ @ Retention (RetentionPolicy .RUNTIME )
321+ @ Target (ElementType .FIELD )
322+ @ Constraint (validatedBy =InnerValidator .class )
323+ public static @interface InnerValid {
324+ String message () default "NOT VALID" ;
325+ Class <?>[] groups () default { };
326+ Class <? extends Payload >[] payload () default {};
327+ }
328+
329+ public static class InnerValidator implements ConstraintValidator <InnerValid , InnerBean > {
330+
331+ @ Override
332+ public void initialize (InnerValid constraintAnnotation ) {
333+ }
334+
335+ @ Override
336+ public boolean isValid (InnerBean bean , ConstraintValidatorContext context ) {
337+ context .disableDefaultConstraintViolation ();
338+ if (bean .getValue () == null ) {
339+ context .buildConstraintViolationWithTemplate ("NULL" ). addNode ("value" ).addConstraintViolation ();
340+ return false ;
341+ }
342+ return true ;
343+ }
344+ }
345+
286346}
0 commit comments