Add global Validator bean to WebReactiveConfiguration
This commit is contained in:
@@ -111,6 +111,7 @@ dependencies {
|
||||
optional "org.eclipse.jetty:jetty-servlet:${jettyVersion}"
|
||||
optional("org.freemarker:freemarker:2.3.23")
|
||||
optional("com.fasterxml:aalto-xml:1.0.0")
|
||||
optional("javax.validation:validation-api:1.0.0.GA")
|
||||
|
||||
provided "javax.servlet:javax.servlet-api:3.1.0"
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ import java.util.Map;
|
||||
|
||||
import reactor.core.converter.DependencyUtils;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -48,6 +50,8 @@ import org.springframework.http.converter.reactive.CodecHttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.ResourceHttpMessageConverter;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.web.reactive.accept.RequestedContentTypeResolver;
|
||||
import org.springframework.web.reactive.accept.RequestedContentTypeResolverBuilder;
|
||||
import org.springframework.web.reactive.result.SimpleHandlerAdapter;
|
||||
@@ -185,6 +189,7 @@ public class WebReactiveConfiguration implements ApplicationContextAware {
|
||||
|
||||
adapter.setMessageConverters(getMessageConverters());
|
||||
adapter.setConversionService(mvcConversionService());
|
||||
adapter.setValidator(mvcValidator());
|
||||
|
||||
return adapter;
|
||||
}
|
||||
@@ -284,6 +289,46 @@ public class WebReactiveConfiguration implements ApplicationContextAware {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a global {@link Validator} instance for example for validating
|
||||
* {@code @RequestBody} method arguments.
|
||||
* <p>Delegates to {@link #getValidator()} first. If that returns {@code null}
|
||||
* checks the classpath for the presence of a JSR-303 implementations
|
||||
* before creating a {@code OptionalValidatorFactoryBean}. If a JSR-303
|
||||
* implementation is not available, a "no-op" {@link Validator} is returned.
|
||||
*/
|
||||
@Bean
|
||||
public Validator mvcValidator() {
|
||||
Validator validator = getValidator();
|
||||
if (validator == null) {
|
||||
if (ClassUtils.isPresent("javax.validation.Validator", getClass().getClassLoader())) {
|
||||
Class<?> clazz;
|
||||
try {
|
||||
String name = "org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean";
|
||||
clazz = ClassUtils.forName(name, classLoader);
|
||||
}
|
||||
catch (ClassNotFoundException ex) {
|
||||
throw new BeanInitializationException("Could not find default validator class", ex);
|
||||
}
|
||||
catch (LinkageError ex) {
|
||||
throw new BeanInitializationException("Could not load default validator class", ex);
|
||||
}
|
||||
validator = (Validator) BeanUtils.instantiate(clazz);
|
||||
}
|
||||
else {
|
||||
validator = new NoOpValidator();
|
||||
}
|
||||
}
|
||||
return validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to provide a custom {@link Validator}.
|
||||
*/
|
||||
protected Validator getValidator() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SimpleHandlerAdapter simpleHandlerAdapter() {
|
||||
return new SimpleHandlerAdapter();
|
||||
@@ -317,4 +362,17 @@ public class WebReactiveConfiguration implements ApplicationContextAware {
|
||||
protected void configureViewResolvers(ViewResolverRegistry registry) {
|
||||
}
|
||||
|
||||
|
||||
private static final class NoOpValidator implements Validator {
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(Object target, Errors errors) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ import org.springframework.http.converter.reactive.CodecHttpMessageConverter;
|
||||
import org.springframework.http.converter.reactive.HttpMessageConverter;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.method.annotation.ExceptionHandlerMethodResolver;
|
||||
import org.springframework.web.reactive.HandlerAdapter;
|
||||
@@ -67,6 +67,8 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory
|
||||
|
||||
private ConversionService conversionService = new DefaultFormattingConversionService();
|
||||
|
||||
private Validator validator;
|
||||
|
||||
private ConfigurableBeanFactory beanFactory;
|
||||
|
||||
private final Map<Class<?>, ExceptionHandlerMethodResolver> exceptionHandlerCache = new ConcurrentHashMap<>(64);
|
||||
@@ -141,6 +143,23 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory
|
||||
return this.conversionService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure a Validator for validation of controller method arguments such
|
||||
* as {@code @RequestBody}.
|
||||
*
|
||||
* TODO: this may be replaced by DataBinder
|
||||
*/
|
||||
public void setValidator(Validator validator) {
|
||||
this.validator = validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the configured Validator.
|
||||
*/
|
||||
public Validator getValidator() {
|
||||
return this.validator;
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link ConfigurableBeanFactory} is expected for resolving expressions
|
||||
* in method argument default values.
|
||||
@@ -173,7 +192,7 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory
|
||||
resolvers.add(new RequestParamMapMethodArgumentResolver());
|
||||
resolvers.add(new PathVariableMethodArgumentResolver(cs, getBeanFactory()));
|
||||
resolvers.add(new PathVariableMapMethodArgumentResolver());
|
||||
resolvers.add(new RequestBodyArgumentResolver(getMessageConverters(), cs));
|
||||
resolvers.add(new RequestBodyArgumentResolver(getMessageConverters(), cs, getValidator()));
|
||||
resolvers.add(new RequestHeaderMethodArgumentResolver(cs, getBeanFactory()));
|
||||
resolvers.add(new RequestHeaderMapMethodArgumentResolver());
|
||||
resolvers.add(new CookieValueMethodArgumentResolver(cs, getBeanFactory()));
|
||||
|
||||
@@ -20,7 +20,6 @@ import java.nio.ByteBuffer;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -50,6 +49,8 @@ import org.springframework.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.MockServerHttpResponse;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean;
|
||||
import org.springframework.web.reactive.accept.RequestedContentTypeResolver;
|
||||
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter;
|
||||
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
|
||||
@@ -148,6 +149,11 @@ public class WebReactiveConfigurationTests {
|
||||
name = "mvcConversionService";
|
||||
ConversionService service = context.getBean(name, ConversionService.class);
|
||||
assertSame(service, adapter.getConversionService());
|
||||
|
||||
name = "mvcValidator";
|
||||
Validator validator = context.getBean(name, Validator.class);
|
||||
assertSame(validator, adapter.getValidator());
|
||||
assertEquals(OptionalValidatorFactoryBean.class, validator.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user