Issue with using custom JSR303 annotation to validate method parameter in Spring mvc container
I build a simple application using Spring, and I try to implement a custom JSR303
annotation to validate method string parameter. I use Java code to config Spring container and I think that I have loaded all the spring beans that I need. But the validation annotation still doesn't work.
Here is the code:
Configure Spring:
@Configuration
@Lazy(false)
public class MVCContainerConfig
{
@Bean
public AnnotationMethodHandlerAdapter annotationMethodHandlerAdapter()
{
ConfigurableWebBindingInitializer configurableWebBindingInitializer = new ConfigurableWebBindingInitializer();
configurableWebBindingInitializer.setValidator(localValidatorFactoryBean());
AnnotationMethodHandlerAdapter annotationMethodHandlerAdapter = new AnnotationMethodHandlerAdapter();
annotationMethodHandlerAdapter.setWebBindingInitializer(configurableWebBindingInitializer);
annotationMethodHandlerAdapter.setMessageConverters(new HttpMessageConverter[]{
new BufferedImageHttpMessageConverter(),
new ByteArrayHttpMessageConverter(),
new FormHttpMessageConverter(),
new ResourceHttpMessageConverter(),
new StringHttpMessageConverter(),
new AtomFeedHttpMessageConverter(),
new RssChannelHttpMessageConverter(),
new MappingJacksonHttpMessageConverter(),
new Jaxb2RootElementHttpMessageConverter(),
new MarshallingHttpMessageConverter(),
new XmlAwareFormHttpMessageConverter()
});
return annotationMethodHandlerAdapter;
}
@Bean
public DefaultAnnotationHandlerMapping defaultAnnotationHandlerMapping()
{
DefaultAnnotationHandlerMapping defaultAnnotationHandlerMapping = new DefaultAnnotationHandlerMapping();
defaultAnnotationHandlerMapping.setInterceptors(new Object[]{localeChangeInterceptor(),
themeChangeInterceptor()});
return defaultAnnotationHandlerMapping;
}
@Bean(name="validator")
public LocalValidatorFactoryBean localValidatorFactoryBean()
{
LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
return localValidatorFactoryBean;
}
... (ignore useless code)
}
Annotation definition:
@Documented
@Constraint(validatedBy={NotEmptyOrWhitespaceValidatorImp.class})
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@ReportAsSingleViolation
@NotNull
public @interface NotEmptyOrWhitespace
{
//TODO change this when language package is ready
public abstract String message() default "Empty or whi开发者_开发知识库te space error message";
public abstract Class<?>[] groups() default { };
public abstract Class<? extends Payload>[] payload() default { };
/**
* Defines several {@code @NotEmptyOrWhitespace} annotations on the same element.
*/
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
public @interface List {
NotEmptyOrWhitespace[] value();
}
}
Constraint definition:
public class NotEmptyOrWhitespaceValidatorImp implements ConstraintValidator<NotEmptyOrWhitespace, String>
{
public void initialize(NotEmptyOrWhitespace annotation){}
public boolean isValid(String str, ConstraintValidatorContext constraintValidatorContext)
{
str = str.replaceAll(" ", "");
return ((str == null || str.isEmpty()) ? false : true);
}
}
The method I want to test:
public boolean isOurProduct(@NotEmptyOrWhitespace String productName)
{
productName = productName.trim().toLowerCase();
return this.productSet.contains(productName);
}
Junit Test method:
@Test
public void testIsOurProduct()
{
// If the annotation works, then I should see an exception occurred instead of the output
System.out.println("********* "+this.finder.isOurProduct(" "));
}
Please see Method Parameter Validation with JSR-303. You need to trigger validation using AOP on method invocation.
精彩评论