Commit d1d70b02 authored by Stephane Nicoll's avatar Stephane Nicoll

Merge branch '1.5.x'

parents c333ccfe 0435f122
...@@ -70,7 +70,6 @@ import org.springframework.util.StringUtils; ...@@ -70,7 +70,6 @@ import org.springframework.util.StringUtils;
import org.springframework.validation.DefaultMessageCodesResolver; import org.springframework.validation.DefaultMessageCodesResolver;
import org.springframework.validation.MessageCodesResolver; import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator; import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean; import org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.SpringValidatorAdapter; import org.springframework.validation.beanvalidation.SpringValidatorAdapter;
import org.springframework.web.accept.ContentNegotiationManager; import org.springframework.web.accept.ContentNegotiationManager;
...@@ -92,7 +91,6 @@ import org.springframework.web.servlet.config.annotation.ResourceChainRegistrati ...@@ -92,7 +91,6 @@ import org.springframework.web.servlet.config.annotation.ResourceChainRegistrati
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver; import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver;
import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping; import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping;
...@@ -161,8 +159,6 @@ public class WebMvcAutoConfiguration { ...@@ -161,8 +159,6 @@ public class WebMvcAutoConfiguration {
private static final Log logger = LogFactory private static final Log logger = LogFactory
.getLog(WebMvcConfigurerAdapter.class); .getLog(WebMvcConfigurerAdapter.class);
private final ApplicationContext applicationContext;
private final ResourceProperties resourceProperties; private final ResourceProperties resourceProperties;
private final WebMvcProperties mvcProperties; private final WebMvcProperties mvcProperties;
...@@ -171,39 +167,20 @@ public class WebMvcAutoConfiguration { ...@@ -171,39 +167,20 @@ public class WebMvcAutoConfiguration {
private final HttpMessageConverters messageConverters; private final HttpMessageConverters messageConverters;
private final Validator userDefinedValidator;
final ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer; final ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer;
public WebMvcAutoConfigurationAdapter(ApplicationContext applicationContext, public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties,
ResourceProperties resourceProperties, WebMvcProperties mvcProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory,
ListableBeanFactory beanFactory, HttpMessageConverters messageConverters, HttpMessageConverters messageConverters,
ObjectProvider<List<WebMvcConfigurer>> webMvcConfigurers,
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider) { ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider) {
this.applicationContext = applicationContext;
this.resourceProperties = resourceProperties; this.resourceProperties = resourceProperties;
this.mvcProperties = mvcProperties; this.mvcProperties = mvcProperties;
this.beanFactory = beanFactory; this.beanFactory = beanFactory;
this.messageConverters = messageConverters; this.messageConverters = messageConverters;
this.userDefinedValidator = findUserDefinedValidator(
webMvcConfigurers.getIfAvailable());
this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider
.getIfAvailable(); .getIfAvailable();
} }
private static Validator findUserDefinedValidator(
List<WebMvcConfigurer> webMvcConfigurers) {
if (webMvcConfigurers != null) {
for (WebMvcConfigurer webMvcConfigurer : webMvcConfigurers) {
Validator validator = webMvcConfigurer.getValidator();
if (validator != null) {
return validator;
}
}
}
return null;
}
@Override @Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.addAll(this.messageConverters.getConverters()); converters.addAll(this.messageConverters.getConverters());
...@@ -299,23 +276,6 @@ public class WebMvcAutoConfiguration { ...@@ -299,23 +276,6 @@ public class WebMvcAutoConfiguration {
} }
} }
@Override
public Validator getValidator() {
// We want to make sure that the exposed 'mvcValidator' bean isn't going to
// expose the standard JSR-303 type
if (isJsr303Present() && this.userDefinedValidator == null) {
return new Jsr303ValidatorHandler(this.applicationContext)
.wrapJsr303Validator();
}
return null; // Keep default or user defined, if any
}
private boolean isJsr303Present() {
return ClassUtils.isPresent(JSR303_VALIDATOR_CLASS,
this.applicationContext.getClassLoader());
}
private <T> Collection<T> getBeansOfType(Class<T> type) { private <T> Collection<T> getBeansOfType(Class<T> type) {
return this.beanFactory.getBeansOfType(type).values(); return this.beanFactory.getBeansOfType(type).values();
} }
...@@ -443,6 +403,22 @@ public class WebMvcAutoConfiguration { ...@@ -443,6 +403,22 @@ public class WebMvcAutoConfiguration {
return super.requestMappingHandlerMapping(); return super.requestMappingHandlerMapping();
} }
@Bean
@Override
public Validator mvcValidator() {
if (isJsr303Present()) {
Validator userDefinedValidator = getValidator();
return new Jsr303ValidatorHandler(getApplicationContext(),
userDefinedValidator).wrapJsr303Validator();
}
return super.mvcValidator();
}
private boolean isJsr303Present() {
return ClassUtils.isPresent(JSR303_VALIDATOR_CLASS,
getApplicationContext().getClassLoader());
}
@Override @Override
protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() { protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
if (this.mvcRegistrations != null if (this.mvcRegistrations != null
...@@ -588,21 +564,27 @@ public class WebMvcAutoConfiguration { ...@@ -588,21 +564,27 @@ public class WebMvcAutoConfiguration {
private final ApplicationContext applicationContext; private final ApplicationContext applicationContext;
Jsr303ValidatorHandler(ApplicationContext applicationContext) { private final Validator userDefinedValidator;
Jsr303ValidatorHandler(ApplicationContext applicationContext,
Validator userDefinedValidator) {
this.applicationContext = applicationContext; this.applicationContext = applicationContext;
this.userDefinedValidator = userDefinedValidator;
} }
public Validator wrapJsr303Validator() { public Validator wrapJsr303Validator() {
try { try {
javax.validation.Validator validator = this.applicationContext if (this.userDefinedValidator != null) {
.getBean(javax.validation.Validator.class); if (this.userDefinedValidator instanceof javax.validation.Validator) {
if (validator instanceof LocalValidatorFactoryBean) { return wrap((javax.validation.Validator) this.userDefinedValidator, false);
return new SpringValidatorAdapterWrapper( }
(LocalValidatorFactoryBean) validator, true); else {
return this.userDefinedValidator;
}
} }
else { else {
return new SpringValidatorAdapterWrapper( return wrap(this.applicationContext.getBean(
new SpringValidatorAdapter(validator), false); javax.validation.Validator.class), true);
} }
} }
catch (NoSuchBeanDefinitionException ex) { catch (NoSuchBeanDefinitionException ex) {
...@@ -613,6 +595,25 @@ public class WebMvcAutoConfiguration { ...@@ -613,6 +595,25 @@ public class WebMvcAutoConfiguration {
} }
} }
/**
* Wrap the specified {@code validator}.
* @param validator the validator to wrap
* @param bean {@code true} if the specified {@code validator} is a bean managed
* in the context
* @return a {@link Validator} wrapping the specified argument
*/
private Validator wrap(javax.validation.Validator validator, boolean bean) {
if (validator instanceof SpringValidatorAdapter) {
return new SpringValidatorAdapterWrapper(
(SpringValidatorAdapter) validator, bean);
}
else {
return new SpringValidatorAdapterWrapper(
new SpringValidatorAdapter(validator), false);
}
}
} }
} }
...@@ -666,6 +666,19 @@ public class WebMvcAutoConfigurationTests { ...@@ -666,6 +666,19 @@ public class WebMvcAutoConfigurationTests {
.validator); .validator);
} }
@Test
public void validationCustomConfigurerTakesPrecedenceAndDoNotExposeJsr303() {
load(MvcJsr303Validator.class);
assertThat(this.context.getBeansOfType(ValidatorFactory.class)).isEmpty();
assertThat(this.context.getBeansOfType(javax.validation.Validator.class))
.isEmpty();
assertThat(this.context.getBeansOfType(Validator.class)).hasSize(1);
Validator validator = this.context.getBean(Validator.class);
assertThat(validator).isInstanceOf(SpringValidatorAdapterWrapper.class);
assertThat(((SpringValidatorAdapterWrapper) validator).getTarget())
.isSameAs(this.context.getBean(MvcJsr303Validator.class).validator);
}
@Test @Test
public void validationJsr303CustomValidatorReusedAsSpringValidator() { public void validationJsr303CustomValidatorReusedAsSpringValidator() {
load(CustomValidator.class); load(CustomValidator.class);
...@@ -884,6 +897,18 @@ public class WebMvcAutoConfigurationTests { ...@@ -884,6 +897,18 @@ public class WebMvcAutoConfigurationTests {
} }
@Configuration
protected static class MvcJsr303Validator extends WebMvcConfigurerAdapter {
private final LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
@Override
public Validator getValidator() {
return this.validator;
}
}
@Configuration @Configuration
static class Jsr303Validator { static class Jsr303Validator {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment