Introduce base class for WebMvcConfiguration
This commit is contained in:
parent
c60511bf04
commit
00d57907a3
|
@ -20,14 +20,13 @@ import java.lang.annotation.Target;
|
|||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
|
||||
/**
|
||||
* Enables default Spring MVC configuration and registers Spring MVC infrastructure components expected by the
|
||||
* {@link DispatcherServlet}. To use this annotation simply place it on an application @{@link Configuration} class
|
||||
* and that will in turn import default Spring MVC configuration including support for annotated methods
|
||||
* in @{@link Controller} classes.
|
||||
* {@link DispatcherServlet}. Add this annotation to an application @{@link Configuration} class. It will in
|
||||
* turn import the @{@link Configuration} class {@link WebMvcConfiguration}, which provides default Spring MVC
|
||||
* configuration.
|
||||
* <pre>
|
||||
* @Configuration
|
||||
* @EnableWebMvc
|
||||
|
@ -39,11 +38,10 @@ import org.springframework.web.servlet.DispatcherServlet;
|
|||
*
|
||||
* }
|
||||
* </pre>
|
||||
* <p>To customize the imported configuration you simply implement {@link WebMvcConfigurer}, or more likely extend
|
||||
* {@link WebMvcConfigurerAdapter} overriding selected methods only. The most obvious place to do this is
|
||||
* the @{@link Configuration} class that enabled the Spring MVC configuration via @{@link EnableWebMvc}.
|
||||
* However any @{@link Configuration} class and more generally any Spring bean can implement {@link WebMvcConfigurer}
|
||||
* to be detected and given an opportunity to customize Spring MVC configuration at startup.
|
||||
* <p>To customize the imported configuration implement {@link WebMvcConfigurer}, or more conveniently extend
|
||||
* {@link WebMvcConfigurerAdapter} overriding specific methods. Your @{@link Configuration} class and any other
|
||||
* Spring bean that implements {@link WebMvcConfigurer} will be detected and given an opportunity to customize
|
||||
* the default Spring MVC configuration through the callback methods on the {@link WebMvcConfigurer} interface.
|
||||
* <pre>
|
||||
* @Configuration
|
||||
* @EnableWebMvc
|
||||
|
|
|
@ -22,77 +22,74 @@ import java.util.List;
|
|||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.context.request.WebRequestInterceptor;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.handler.MappedInterceptor;
|
||||
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter;
|
||||
|
||||
/**
|
||||
* Helps with configuring an ordered set of Spring MVC interceptors of type {@link HandlerInterceptor} or
|
||||
* {@link WebRequestInterceptor}. Registered interceptors will generally be detected by all {@link HandlerMapping}
|
||||
* instances in a Spring MVC web application context. Interceptors can be added with a set of path patterns to
|
||||
* which they should apply.
|
||||
* {@link WebRequestInterceptor}. Interceptors can be registered with a set of path patterns.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
*/
|
||||
public class InterceptorConfigurer {
|
||||
|
||||
private final List<MappedInterceptor> mappedInterceptors = new ArrayList<MappedInterceptor>();
|
||||
private final List<Object> interceptors = new ArrayList<Object>();
|
||||
|
||||
/**
|
||||
* Add a {@link HandlerInterceptor} that should apply to any request.
|
||||
*/
|
||||
public void addInterceptor(HandlerInterceptor interceptor) {
|
||||
register(null, interceptor);
|
||||
register(interceptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a {@link WebRequestInterceptor} that should apply to any request.
|
||||
*/
|
||||
public void addInterceptor(WebRequestInterceptor interceptor) {
|
||||
register(null, asHandlerInterceptorArray(interceptor));
|
||||
register(asHandlerInterceptorArray(interceptor));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@link HandlerInterceptor}s that should apply to any request.
|
||||
*/
|
||||
public void addInterceptors(HandlerInterceptor... interceptors) {
|
||||
register(null, interceptors);
|
||||
register( interceptors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@link WebRequestInterceptor}s that should apply to any request.
|
||||
*/
|
||||
public void addInterceptors(WebRequestInterceptor... interceptors) {
|
||||
register(null, asHandlerInterceptorArray(interceptors));
|
||||
register(asHandlerInterceptorArray(interceptors));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a {@link HandlerInterceptor} with a set of URL path patterns it should apply to.
|
||||
*/
|
||||
public void mapInterceptor(String[] pathPatterns, HandlerInterceptor interceptor) {
|
||||
register(pathPatterns, interceptor);
|
||||
registerMappedInterceptors(pathPatterns, interceptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a {@link WebRequestInterceptor} with a set of URL path patterns it should apply to.
|
||||
*/
|
||||
public void mapInterceptor(String[] pathPatterns, WebRequestInterceptor interceptors) {
|
||||
register(pathPatterns, asHandlerInterceptorArray(interceptors));
|
||||
registerMappedInterceptors(pathPatterns, asHandlerInterceptorArray(interceptors));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@link HandlerInterceptor}s with a set of URL path patterns they should apply to.
|
||||
*/
|
||||
public void mapInterceptors(String[] pathPatterns, HandlerInterceptor... interceptors) {
|
||||
register(pathPatterns, interceptors);
|
||||
registerMappedInterceptors(pathPatterns, interceptors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@link WebRequestInterceptor}s with a set of URL path patterns they should apply to.
|
||||
*/
|
||||
public void mapInterceptors(String[] pathPatterns, WebRequestInterceptor... interceptors) {
|
||||
register(pathPatterns, asHandlerInterceptorArray(interceptors));
|
||||
registerMappedInterceptors(pathPatterns, asHandlerInterceptorArray(interceptors));
|
||||
}
|
||||
|
||||
private static HandlerInterceptor[] asHandlerInterceptorArray(WebRequestInterceptor...interceptors) {
|
||||
|
@ -103,23 +100,35 @@ public class InterceptorConfigurer {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the given set of {@link HandlerInterceptor}s internally.
|
||||
* @param interceptors one or more interceptors to be stored
|
||||
*/
|
||||
protected void register(HandlerInterceptor...interceptors) {
|
||||
Assert.notEmpty(interceptors, "At least one interceptor must be provided");
|
||||
for (HandlerInterceptor interceptor : interceptors) {
|
||||
this.interceptors.add(interceptor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the given set of {@link HandlerInterceptor}s and path patterns internally.
|
||||
* @param pathPatterns path patterns or {@code null}
|
||||
* @param interceptors one or more interceptors to be stored
|
||||
*/
|
||||
protected void register(String[] pathPatterns, HandlerInterceptor...interceptors) {
|
||||
protected void registerMappedInterceptors(String[] pathPatterns, HandlerInterceptor...interceptors) {
|
||||
Assert.notEmpty(interceptors, "At least one interceptor must be provided");
|
||||
Assert.notEmpty(pathPatterns, "Path patterns must be provided");
|
||||
for (HandlerInterceptor interceptor : interceptors) {
|
||||
mappedInterceptors.add(new MappedInterceptor(pathPatterns, interceptor));
|
||||
this.interceptors.add(new MappedInterceptor(pathPatterns, interceptor));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all registered interceptors.
|
||||
*/
|
||||
protected List<MappedInterceptor> getInterceptors() {
|
||||
return mappedInterceptors;
|
||||
protected List<Object> getInterceptors() {
|
||||
return interceptors;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,95 +19,31 @@ package org.springframework.web.servlet.config.annotation;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.xml.transform.Source;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.format.support.DefaultFormattingConversionService;
|
||||
import org.springframework.format.support.FormattingConversionService;
|
||||
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.ResourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.http.converter.feed.AtomFeedHttpMessageConverter;
|
||||
import org.springframework.http.converter.feed.RssChannelHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.web.HttpRequestHandler;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
||||
import org.springframework.web.context.ServletContextAware;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;
|
||||
import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor;
|
||||
import org.springframework.web.servlet.handler.HandlerExceptionResolverComposite;
|
||||
import org.springframework.web.servlet.handler.MappedInterceptor;
|
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||
import org.springframework.web.servlet.mvc.Controller;
|
||||
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
|
||||
import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
|
||||
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
||||
|
||||
/**
|
||||
* Provides default configuration for Spring MVC applications. Registers Spring MVC infrastructure components to be
|
||||
* detected by the {@link DispatcherServlet}. Further below is a list of registered instances. This configuration is
|
||||
* enabled through the {@link EnableWebMvc} annotation.
|
||||
*
|
||||
* <p>A number of options are available for customizing the default configuration provided by this class.
|
||||
* See {@link EnableWebMvc} and {@link WebMvcConfigurer} for details.
|
||||
*
|
||||
* <p>Registers these handler mappings:
|
||||
* <ul>
|
||||
* <li>{@link RequestMappingHandlerMapping} ordered at 0 for mapping requests to annotated controller methods.
|
||||
* <li>{@link SimpleUrlHandlerMapping} ordered at 1 to map URL paths directly to view names.
|
||||
* <li>{@link BeanNameUrlHandlerMapping} ordered at 2 to map URL paths to controller bean names.
|
||||
* <li>{@link SimpleUrlHandlerMapping} ordered at {@code Integer.MAX_VALUE-1} to serve static resource requests.
|
||||
* <li>{@link SimpleUrlHandlerMapping} ordered at {@code Integer.MAX_VALUE} to forward requests to the default servlet.
|
||||
* </ul>
|
||||
*
|
||||
* <p><strong>Note:</strong> that the SimpleUrlHandlerMapping instances above will have empty URL maps and
|
||||
* hence no effect until explicitly configured via one of the {@link WebMvcConfigurer} callbacks.
|
||||
*
|
||||
* <p>Registers these handler adapters:
|
||||
* <ul>
|
||||
* <li>{@link RequestMappingHandlerAdapter} for processing requests using annotated controller methods.
|
||||
* <li>{@link HttpRequestHandlerAdapter} for processing requests with {@link HttpRequestHandler}s.
|
||||
* <li>{@link SimpleControllerHandlerAdapter} for processing requests with interface-based {@link Controller}s.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Registers a {@link HandlerExceptionResolverComposite} with this chain of exception resolvers:
|
||||
* <ul>
|
||||
* <li>{@link ExceptionHandlerExceptionResolver} for handling exceptions through @{@link ExceptionHandler} methods.
|
||||
* <li>{@link ResponseStatusExceptionResolver} for exceptions annotated with @{@link ResponseStatus}.
|
||||
* <li>{@link DefaultHandlerExceptionResolver} for resolving known Spring exception types
|
||||
* </ul>
|
||||
*
|
||||
* <p>Registers the following others:
|
||||
* <ul>
|
||||
* <li>{@link FormattingConversionService} for use with annotated controller methods and the spring:eval JSP tag.
|
||||
* <li>{@link Validator} for validating model attributes on annotated controller methods.
|
||||
* </ul>
|
||||
* Provides default configuration for Spring MVC applications by registering Spring MVC infrastructure components
|
||||
* to be detected by the {@link DispatcherServlet}. This class is imported whenever @{@link EnableWebMvc} is
|
||||
* added to an @{@link Configuration} class.
|
||||
*
|
||||
* <p>See the base class {@link WebMvcConfigurationSupport} for a list of registered instances. This class is closed
|
||||
* for extension. However, the configuration it provides can be customized by having your @{@link Configuration}
|
||||
* class implement {@link WebMvcConfigurer} or more conveniently extend from {@link WebMvcConfigurerAdapter}.
|
||||
*
|
||||
* <p>This class will detect your @{@link Configuration} class and any other @{@link Configuration} classes that
|
||||
* implement {@link WebMvcConfigurer} via autowiring and will allow each of them to participate in the process
|
||||
* of configuring Spring MVC through the configuration callbacks defined in {@link WebMvcConfigurer}.
|
||||
*
|
||||
* @see EnableWebMvc
|
||||
* @see WebMvcConfigurer
|
||||
|
@ -116,18 +52,10 @@ import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolv
|
|||
* @since 3.1
|
||||
*/
|
||||
@Configuration
|
||||
class WebMvcConfiguration implements ApplicationContextAware, ServletContextAware {
|
||||
class WebMvcConfiguration extends WebMvcConfigurationSupport {
|
||||
|
||||
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
|
||||
|
||||
private ServletContext servletContext;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private List<MappedInterceptor> mappedInterceptors;
|
||||
|
||||
private List<HttpMessageConverter<?>> messageConverters;
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setConfigurers(List<WebMvcConfigurer> configurers) {
|
||||
if (configurers == null || configurers.isEmpty()) {
|
||||
|
@ -136,75 +64,30 @@ class WebMvcConfiguration implements ApplicationContextAware, ServletContextAwar
|
|||
this.configurers.addWebMvcConfigurers(configurers);
|
||||
}
|
||||
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
this.servletContext = servletContext;
|
||||
@Override
|
||||
protected void configureInterceptors(InterceptorConfigurer configurer) {
|
||||
configurers.configureInterceptors(configurer);
|
||||
}
|
||||
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
|
||||
RequestMappingHandlerMapping mapping = new RequestMappingHandlerMapping();
|
||||
mapping.setInterceptors(getMappedInterceptors());
|
||||
mapping.setOrder(0);
|
||||
return mapping;
|
||||
}
|
||||
|
||||
private Object[] getMappedInterceptors() {
|
||||
if (mappedInterceptors == null) {
|
||||
InterceptorConfigurer configurer = new InterceptorConfigurer();
|
||||
configurers.configureInterceptors(configurer);
|
||||
configurer.addInterceptor(new ConversionServiceExposingInterceptor(conversionService()));
|
||||
mappedInterceptors = configurer.getInterceptors();
|
||||
}
|
||||
return mappedInterceptors.toArray();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HandlerMapping viewControllerHandlerMapping() {
|
||||
ViewControllerConfigurer configurer = new ViewControllerConfigurer();
|
||||
configurer.setOrder(1);
|
||||
@Override
|
||||
protected void configureViewControllers(ViewControllerConfigurer configurer) {
|
||||
configurers.configureViewControllers(configurer);
|
||||
|
||||
SimpleUrlHandlerMapping handlerMapping = configurer.getHandlerMapping();
|
||||
handlerMapping.setInterceptors(getMappedInterceptors());
|
||||
return handlerMapping;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BeanNameUrlHandlerMapping beanNameHandlerMapping() {
|
||||
BeanNameUrlHandlerMapping mapping = new BeanNameUrlHandlerMapping();
|
||||
mapping.setOrder(2);
|
||||
mapping.setInterceptors(getMappedInterceptors());
|
||||
return mapping;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HandlerMapping resourceHandlerMapping() {
|
||||
ResourceConfigurer configurer = new ResourceConfigurer(applicationContext, servletContext);
|
||||
configurer.setOrder(Integer.MAX_VALUE-1);
|
||||
@Override
|
||||
protected void configureResourceHandling(ResourceConfigurer configurer) {
|
||||
configurers.configureResourceHandling(configurer);
|
||||
return configurer.getHandlerMapping();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HandlerMapping defaultServletHandlerMapping() {
|
||||
DefaultServletHandlerConfigurer configurer = new DefaultServletHandlerConfigurer(servletContext);
|
||||
@Override
|
||||
protected void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
|
||||
configurers.configureDefaultServletHandling(configurer);
|
||||
return configurer.getHandlerMapping();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
|
||||
RequestMappingHandlerAdapter adapter = new RequestMappingHandlerAdapter();
|
||||
adapter.setMessageConverters(getMessageConverters());
|
||||
|
||||
ConfigurableWebBindingInitializer bindingInitializer = new ConfigurableWebBindingInitializer();
|
||||
bindingInitializer.setConversionService(conversionService());
|
||||
bindingInitializer.setValidator(validator());
|
||||
adapter.setWebBindingInitializer(bindingInitializer);
|
||||
RequestMappingHandlerAdapter adapter = super.requestMappingHandlerAdapter();
|
||||
|
||||
List<HandlerMethodArgumentResolver> argumentResolvers = new ArrayList<HandlerMethodArgumentResolver>();
|
||||
configurers.addArgumentResolvers(argumentResolvers);
|
||||
|
@ -213,116 +96,40 @@ class WebMvcConfiguration implements ApplicationContextAware, ServletContextAwar
|
|||
List<HandlerMethodReturnValueHandler> returnValueHandlers = new ArrayList<HandlerMethodReturnValueHandler>();
|
||||
configurers.addReturnValueHandlers(returnValueHandlers);
|
||||
adapter.setCustomReturnValueHandlers(returnValueHandlers);
|
||||
|
||||
|
||||
return adapter;
|
||||
}
|
||||
|
||||
private List<HttpMessageConverter<?>> getMessageConverters() {
|
||||
if (messageConverters == null) {
|
||||
messageConverters = new ArrayList<HttpMessageConverter<?>>();
|
||||
configurers.configureMessageConverters(messageConverters);
|
||||
if (messageConverters.isEmpty()) {
|
||||
addDefaultHttpMessageConverters(messageConverters);
|
||||
}
|
||||
}
|
||||
return messageConverters;
|
||||
@Override
|
||||
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
configurers.configureMessageConverters(converters);
|
||||
}
|
||||
|
||||
@Bean(name="webMvcConversionService")
|
||||
public FormattingConversionService conversionService() {
|
||||
FormattingConversionService conversionService = new DefaultFormattingConversionService();
|
||||
|
||||
@Override
|
||||
@Bean
|
||||
public FormattingConversionService mvcConversionService() {
|
||||
FormattingConversionService conversionService = super.mvcConversionService();
|
||||
configurers.addFormatters(conversionService);
|
||||
return conversionService;
|
||||
}
|
||||
|
||||
@Bean(name="webMvcValidator")
|
||||
public Validator validator() {
|
||||
@Override
|
||||
@Bean
|
||||
public Validator mvcValidator() {
|
||||
Validator validator = configurers.getValidator();
|
||||
if (validator != null) {
|
||||
return validator;
|
||||
}
|
||||
else if (ClassUtils.isPresent("javax.validation.Validator", getClass().getClassLoader())) {
|
||||
Class<?> clazz;
|
||||
try {
|
||||
String className = "org.springframework.validation.beanvalidation.LocalValidatorFactoryBean";
|
||||
clazz = ClassUtils.forName(className, WebMvcConfiguration.class.getClassLoader());
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new BeanInitializationException("Could not find default validator");
|
||||
} catch (LinkageError e) {
|
||||
throw new BeanInitializationException("Could not find default validator");
|
||||
}
|
||||
return (Validator) BeanUtils.instantiate(clazz);
|
||||
}
|
||||
else {
|
||||
return NOOP_VALIDATOR;
|
||||
}
|
||||
}
|
||||
|
||||
private void addDefaultHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
|
||||
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
|
||||
stringConverter.setWriteAcceptCharset(false);
|
||||
|
||||
messageConverters.add(new ByteArrayHttpMessageConverter());
|
||||
messageConverters.add(stringConverter);
|
||||
messageConverters.add(new ResourceHttpMessageConverter());
|
||||
messageConverters.add(new SourceHttpMessageConverter<Source>());
|
||||
messageConverters.add(new XmlAwareFormHttpMessageConverter());
|
||||
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
if (ClassUtils.isPresent("javax.xml.bind.Binder", classLoader)) {
|
||||
messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
|
||||
}
|
||||
if (ClassUtils.isPresent("org.codehaus.jackson.map.ObjectMapper", classLoader)) {
|
||||
messageConverters.add(new MappingJacksonHttpMessageConverter());
|
||||
}
|
||||
if (ClassUtils.isPresent("com.sun.syndication.feed.WireFeed", classLoader)) {
|
||||
messageConverters.add(new AtomFeedHttpMessageConverter());
|
||||
messageConverters.add(new RssChannelHttpMessageConverter());
|
||||
}
|
||||
return validator != null ? validator : super.mvcValidator();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HttpRequestHandlerAdapter httpRequestHandlerAdapter() {
|
||||
return new HttpRequestHandlerAdapter();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SimpleControllerHandlerAdapter simpleControllerHandlerAdapter() {
|
||||
return new SimpleControllerHandlerAdapter();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HandlerExceptionResolver handlerExceptionResolver() throws Exception {
|
||||
public HandlerExceptionResolverComposite handlerExceptionResolver() throws Exception {
|
||||
List<HandlerExceptionResolver> resolvers = new ArrayList<HandlerExceptionResolver>();
|
||||
configurers.configureHandlerExceptionResolvers(resolvers);
|
||||
|
||||
if (resolvers.size() == 0) {
|
||||
resolvers.add(createExceptionHandlerExceptionResolver());
|
||||
resolvers.add(new ResponseStatusExceptionResolver());
|
||||
resolvers.add(new DefaultHandlerExceptionResolver());
|
||||
HandlerExceptionResolverComposite composite = super.handlerExceptionResolver();
|
||||
if (resolvers.size() != 0) {
|
||||
composite.setExceptionResolvers(resolvers);
|
||||
}
|
||||
|
||||
HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();
|
||||
composite.setOrder(0);
|
||||
composite.setExceptionResolvers(resolvers);
|
||||
return composite;
|
||||
}
|
||||
|
||||
private HandlerExceptionResolver createExceptionHandlerExceptionResolver() throws Exception {
|
||||
ExceptionHandlerExceptionResolver resolver = new ExceptionHandlerExceptionResolver();
|
||||
resolver.setMessageConverters(getMessageConverters());
|
||||
resolver.afterPropertiesSet();
|
||||
return resolver;
|
||||
}
|
||||
|
||||
private static final Validator NOOP_VALIDATOR = new Validator() {
|
||||
|
||||
public boolean supports(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void validate(Object target, Errors errors) {
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,399 @@
|
|||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.config.annotation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.xml.transform.Source;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.format.support.DefaultFormattingConversionService;
|
||||
import org.springframework.format.support.FormattingConversionService;
|
||||
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.ResourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.http.converter.feed.AtomFeedHttpMessageConverter;
|
||||
import org.springframework.http.converter.feed.RssChannelHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.MessageCodesResolver;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.web.HttpRequestHandler;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
||||
import org.springframework.web.context.ServletContextAware;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
import org.springframework.web.servlet.HandlerAdapter;
|
||||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;
|
||||
import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor;
|
||||
import org.springframework.web.servlet.handler.HandlerExceptionResolverComposite;
|
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||
import org.springframework.web.servlet.mvc.Controller;
|
||||
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
|
||||
import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
|
||||
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
||||
|
||||
/**
|
||||
* A base class that provides default configuration for Spring MVC applications by registering Spring MVC
|
||||
* infrastructure components to be detected by the {@link DispatcherServlet}. Typically applications should not
|
||||
* have to start by extending this class. A much easier place to start is to annotate your @{@link Configuration}
|
||||
* class with @{@link EnableWebMvc}. See @{@link EnableWebMvc} and {@link WebMvcConfigurer}.
|
||||
*
|
||||
* <p>If using @{@link EnableWebMvc} and extending from {@link WebMvcConfigurerAdapter} does not give you the level
|
||||
* of flexibility you need, consider extending directly from this class instead. Remember to add @{@link Configuration}
|
||||
* to you subclass and @{@link Bean} to any @{@link Bean} methods you choose to override. A few example reasons for
|
||||
* extending this class include providing a custom {@link MessageCodesResolver}, changing the order of
|
||||
* {@link HandlerMapping} instances, plugging in a variant of any of the beans provided by this class, and so on.
|
||||
*
|
||||
* <p>This class registers the following {@link HandlerMapping}s:</p>
|
||||
* <ul>
|
||||
* <li>{@link RequestMappingHandlerMapping} ordered at 0 for mapping requests to annotated controller methods.
|
||||
* <li>{@link SimpleUrlHandlerMapping} ordered at 1 to map URL paths directly to view names.
|
||||
* <li>{@link BeanNameUrlHandlerMapping} ordered at 2 to map URL paths to controller bean names.
|
||||
* <li>{@link SimpleUrlHandlerMapping} ordered at {@code Integer.MAX_VALUE-1} to serve static resource requests.
|
||||
* <li>{@link SimpleUrlHandlerMapping} ordered at {@code Integer.MAX_VALUE} to forward requests to the default servlet.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Registers {@link HandlerAdapter}s:
|
||||
* <ul>
|
||||
* <li>{@link RequestMappingHandlerAdapter} for processing requests using annotated controller methods.
|
||||
* <li>{@link HttpRequestHandlerAdapter} for processing requests with {@link HttpRequestHandler}s.
|
||||
* <li>{@link SimpleControllerHandlerAdapter} for processing requests with interface-based {@link Controller}s.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Registers a {@link HandlerExceptionResolverComposite} with this chain of exception resolvers:
|
||||
* <ul>
|
||||
* <li>{@link ExceptionHandlerExceptionResolver} for handling exceptions through @{@link ExceptionHandler} methods.
|
||||
* <li>{@link ResponseStatusExceptionResolver} for exceptions annotated with @{@link ResponseStatus}.
|
||||
* <li>{@link DefaultHandlerExceptionResolver} for resolving known Spring exception types
|
||||
* </ul>
|
||||
*
|
||||
* <p>Registers the following other instances:
|
||||
* <ul>
|
||||
* <li>{@link FormattingConversionService} for use with annotated controller methods and the spring:eval JSP tag.
|
||||
* <li>{@link Validator} for validating model attributes on annotated controller methods.
|
||||
* </ul>
|
||||
*
|
||||
* @see EnableWebMvc
|
||||
* @see WebMvcConfigurer
|
||||
* @see WebMvcConfigurerAdapter
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
*/
|
||||
public abstract class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {
|
||||
|
||||
private ServletContext servletContext;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
private List<Object> interceptors;
|
||||
|
||||
private List<HttpMessageConverter<?>> messageConverters;
|
||||
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
this.servletContext = servletContext;
|
||||
}
|
||||
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link RequestMappingHandlerMapping} ordered at 0 for mapping requests to annotated controllers.
|
||||
*/
|
||||
@Bean
|
||||
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
|
||||
RequestMappingHandlerMapping mapping = new RequestMappingHandlerMapping();
|
||||
mapping.setInterceptors(getInterceptors());
|
||||
mapping.setOrder(0);
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides access to the shared handler interceptors used to configure {@link HandlerMapping} instances with.
|
||||
* This method cannot be overridden, use {@link #configureInterceptors(InterceptorConfigurer)} instead.
|
||||
*/
|
||||
protected final Object[] getInterceptors() {
|
||||
if (interceptors == null) {
|
||||
InterceptorConfigurer configurer = new InterceptorConfigurer();
|
||||
configureInterceptors(configurer);
|
||||
configurer.addInterceptor(new ConversionServiceExposingInterceptor(mvcConversionService()));
|
||||
interceptors = configurer.getInterceptors();
|
||||
}
|
||||
return interceptors.toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to configure handler interceptors including interceptors mapped to path patterns.
|
||||
* @see InterceptorConfigurer
|
||||
*/
|
||||
protected void configureInterceptors(InterceptorConfigurer configurer) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link SimpleUrlHandlerMapping} ordered at 1 to map URL paths directly to view names.
|
||||
* To configure view controllers see {@link #configureViewControllers(ViewControllerConfigurer)}.
|
||||
*/
|
||||
@Bean
|
||||
public SimpleUrlHandlerMapping viewControllerHandlerMapping() {
|
||||
ViewControllerConfigurer configurer = new ViewControllerConfigurer();
|
||||
configurer.setOrder(1);
|
||||
configureViewControllers(configurer);
|
||||
|
||||
SimpleUrlHandlerMapping handlerMapping = configurer.getHandlerMapping();
|
||||
handlerMapping.setInterceptors(getInterceptors());
|
||||
return handlerMapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to configure view controllers. View controllers provide a direct mapping between a
|
||||
* URL path and view name. This is useful when serving requests that don't require application-specific
|
||||
* controller logic and can be forwarded directly to a view for rendering.
|
||||
* @see ViewControllerConfigurer
|
||||
*/
|
||||
protected void configureViewControllers(ViewControllerConfigurer configurer) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link BeanNameUrlHandlerMapping} ordered at 2 to map URL paths to controller bean names.
|
||||
*/
|
||||
@Bean
|
||||
public BeanNameUrlHandlerMapping beanNameHandlerMapping() {
|
||||
BeanNameUrlHandlerMapping mapping = new BeanNameUrlHandlerMapping();
|
||||
mapping.setOrder(2);
|
||||
mapping.setInterceptors(getInterceptors());
|
||||
return mapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link SimpleUrlHandlerMapping} ordered at Integer.MAX_VALUE-1 to serve static resource requests.
|
||||
* To configure resource handling, see {@link #configureResourceHandling(ResourceConfigurer)}.
|
||||
*/
|
||||
@Bean
|
||||
public SimpleUrlHandlerMapping resourceHandlerMapping() {
|
||||
ResourceConfigurer configurer = new ResourceConfigurer(applicationContext, servletContext);
|
||||
configurer.setOrder(Integer.MAX_VALUE-1);
|
||||
configureResourceHandling(configurer);
|
||||
return configurer.getHandlerMapping();
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to configure serving static resources such as images and css files through Spring MVC.
|
||||
* @see ResourceConfigurer
|
||||
*/
|
||||
protected void configureResourceHandling(ResourceConfigurer configurer) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link SimpleUrlHandlerMapping} ordered at Integer.MAX_VALUE to serve static resources by
|
||||
* forwarding to the Servlet container's default servlet. To configure default servlet handling see
|
||||
* {@link #configureDefaultServletHandling(DefaultServletHandlerConfigurer)}.
|
||||
*/
|
||||
@Bean
|
||||
public SimpleUrlHandlerMapping defaultServletHandlerMapping() {
|
||||
DefaultServletHandlerConfigurer configurer = new DefaultServletHandlerConfigurer(servletContext);
|
||||
configureDefaultServletHandling(configurer);
|
||||
return configurer.getHandlerMapping();
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to configure serving static resources through the Servlet container's default Servlet.
|
||||
* @see DefaultServletHandlerConfigurer
|
||||
*/
|
||||
protected void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link RequestMappingHandlerAdapter} for processing requests using annotated controller methods.
|
||||
* Also see {@link #initWebBindingInitializer()} for configuring data binding globally.
|
||||
*/
|
||||
@Bean
|
||||
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
|
||||
ConfigurableWebBindingInitializer webBindingInitializer = new ConfigurableWebBindingInitializer();
|
||||
webBindingInitializer.setConversionService(mvcConversionService());
|
||||
webBindingInitializer.setValidator(mvcValidator());
|
||||
extendWebBindingInitializer(webBindingInitializer);
|
||||
|
||||
RequestMappingHandlerAdapter adapter = new RequestMappingHandlerAdapter();
|
||||
adapter.setMessageConverters(getMessageConverters());
|
||||
adapter.setWebBindingInitializer(webBindingInitializer);
|
||||
return adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to customize the {@link ConfigurableWebBindingInitializer} the
|
||||
* {@link RequestMappingHandlerAdapter} is configured with.
|
||||
*/
|
||||
protected void extendWebBindingInitializer(ConfigurableWebBindingInitializer webBindingInitializer) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides access to the shared {@link HttpMessageConverter}s used by the
|
||||
* {@link RequestMappingHandlerAdapter} and the {@link ExceptionHandlerExceptionResolver}.
|
||||
* This method cannot be extended directly, use {@link #configureMessageConverters(List)} add custom converters.
|
||||
* Also see {@link #addDefaultHttpMessageConverters(List)} to easily add a set of default converters.
|
||||
*/
|
||||
protected final List<HttpMessageConverter<?>> getMessageConverters() {
|
||||
if (messageConverters == null) {
|
||||
messageConverters = new ArrayList<HttpMessageConverter<?>>();
|
||||
configureMessageConverters(messageConverters);
|
||||
if (messageConverters.isEmpty()) {
|
||||
addDefaultHttpMessageConverters(messageConverters);
|
||||
}
|
||||
}
|
||||
return messageConverters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to add custom {@link HttpMessageConverter}s to use with
|
||||
* the {@link RequestMappingHandlerAdapter} and the {@link ExceptionHandlerExceptionResolver}.
|
||||
* If any converters are added, default converters will not be added automatically.
|
||||
* See {@link #addDefaultHttpMessageConverters(List)} for adding default converters to the list.
|
||||
* @param messageConverters the list to add converters to
|
||||
*/
|
||||
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
}
|
||||
|
||||
/**
|
||||
* A method available to subclasses for adding default {@link HttpMessageConverter}s.
|
||||
* @param messageConverters the list to add converters to
|
||||
*/
|
||||
protected final void addDefaultHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
|
||||
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
|
||||
stringConverter.setWriteAcceptCharset(false);
|
||||
|
||||
messageConverters.add(new ByteArrayHttpMessageConverter());
|
||||
messageConverters.add(stringConverter);
|
||||
messageConverters.add(new ResourceHttpMessageConverter());
|
||||
messageConverters.add(new SourceHttpMessageConverter<Source>());
|
||||
messageConverters.add(new XmlAwareFormHttpMessageConverter());
|
||||
|
||||
ClassLoader classLoader = getClass().getClassLoader();
|
||||
if (ClassUtils.isPresent("javax.xml.bind.Binder", classLoader)) {
|
||||
messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
|
||||
}
|
||||
if (ClassUtils.isPresent("org.codehaus.jackson.map.ObjectMapper", classLoader)) {
|
||||
messageConverters.add(new MappingJacksonHttpMessageConverter());
|
||||
}
|
||||
if (ClassUtils.isPresent("com.sun.syndication.feed.WireFeed", classLoader)) {
|
||||
messageConverters.add(new AtomFeedHttpMessageConverter());
|
||||
messageConverters.add(new RssChannelHttpMessageConverter());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link FormattingConversionService} for use with annotated controller methods and the
|
||||
* {@code spring:eval} JSP tag.
|
||||
*/
|
||||
@Bean
|
||||
public FormattingConversionService mvcConversionService() {
|
||||
return new DefaultFormattingConversionService();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link Validator} for validating {@code @ModelAttribute} and {@code @RequestBody} arguments of
|
||||
* annotated controller methods. If a JSR-303 implementation is available on the classpath, the returned
|
||||
* instance is LocalValidatorFactoryBean. Otherwise a no-op validator is returned.
|
||||
*/
|
||||
@Bean
|
||||
public Validator mvcValidator() {
|
||||
if (ClassUtils.isPresent("javax.validation.Validator", getClass().getClassLoader())) {
|
||||
Class<?> clazz;
|
||||
try {
|
||||
String className = "org.springframework.validation.beanvalidation.LocalValidatorFactoryBean";
|
||||
clazz = ClassUtils.forName(className, WebMvcConfigurationSupport.class.getClassLoader());
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new BeanInitializationException("Could not find default validator");
|
||||
} catch (LinkageError e) {
|
||||
throw new BeanInitializationException("Could not find default validator");
|
||||
}
|
||||
return (Validator) BeanUtils.instantiate(clazz);
|
||||
}
|
||||
else {
|
||||
return new Validator() {
|
||||
public boolean supports(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
public void validate(Object target, Errors errors) {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link HttpRequestHandlerAdapter} for processing requests with {@link HttpRequestHandler}s.
|
||||
*/
|
||||
@Bean
|
||||
public HttpRequestHandlerAdapter httpRequestHandlerAdapter() {
|
||||
return new HttpRequestHandlerAdapter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link SimpleControllerHandlerAdapter} for processing requests with interface-based controllers.
|
||||
*/
|
||||
@Bean
|
||||
public SimpleControllerHandlerAdapter simpleControllerHandlerAdapter() {
|
||||
return new SimpleControllerHandlerAdapter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link HandlerExceptionResolverComposite} with this chain of exception resolvers:
|
||||
* <ul>
|
||||
* <li>{@link ExceptionHandlerExceptionResolver} for handling exceptions through @{@link ExceptionHandler} methods.
|
||||
* <li>{@link ResponseStatusExceptionResolver} for exceptions annotated with @{@link ResponseStatus}.
|
||||
* <li>{@link DefaultHandlerExceptionResolver} for resolving known Spring exception types
|
||||
* </ul>
|
||||
*/
|
||||
@Bean
|
||||
public HandlerExceptionResolverComposite handlerExceptionResolver() throws Exception {
|
||||
ExceptionHandlerExceptionResolver exceptionHandlerExceptionResolver = new ExceptionHandlerExceptionResolver();
|
||||
exceptionHandlerExceptionResolver.setMessageConverters(getMessageConverters());
|
||||
exceptionHandlerExceptionResolver.afterPropertiesSet();
|
||||
|
||||
List<HandlerExceptionResolver> exceptionResolvers = new ArrayList<HandlerExceptionResolver>();
|
||||
exceptionResolvers.add(exceptionHandlerExceptionResolver);
|
||||
exceptionResolvers.add(new ResponseStatusExceptionResolver());
|
||||
exceptionResolvers.add(new DefaultHandlerExceptionResolver());
|
||||
|
||||
HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();
|
||||
composite.setOrder(0);
|
||||
composite.setExceptionResolvers(exceptionResolvers);
|
||||
return composite;
|
||||
}
|
||||
|
||||
}
|
|
@ -18,7 +18,6 @@ package org.springframework.web.servlet.config.annotation;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.format.Formatter;
|
||||
import org.springframework.format.FormatterRegistry;
|
||||
|
@ -35,14 +34,13 @@ import org.springframework.web.servlet.HandlerInterceptor;
|
|||
import com.sun.corba.se.impl.presentation.rmi.ExceptionHandler;
|
||||
|
||||
/**
|
||||
* Defines options for customizing or adding to the default Spring MVC configuration enabled through the use
|
||||
* of @{@link EnableWebMvc}. The @{@link Configuration} class annotated with @{@link EnableWebMvc}
|
||||
* is the most obvious place to implement this interface. However all @{@link Configuration} classes and more generally
|
||||
* all Spring beans that implement this interface will be detected at startup and given a chance to customize Spring
|
||||
* MVC configuration provided it is enabled through @{@link EnableWebMvc}.
|
||||
*
|
||||
* <p>Implementations of this interface will find it convenient to extend {@link WebMvcConfigurerAdapter} that
|
||||
* provides default method implementations and allows overriding only methods of interest.
|
||||
* Defines configuration callback methods for customizing the default Spring MVC configuration enabled through the
|
||||
* use of @{@link EnableWebMvc}.
|
||||
*
|
||||
* <p>Classes annotated with @{@link EnableWebMvc} can implement this interface in order to be called back and
|
||||
* given a chance to customize the default configuration. The most convenient way to implement this interface is
|
||||
* by extending from {@link WebMvcConfigurerAdapter}, which provides empty method implementations and allows
|
||||
* overriding only the callback methods you're interested in.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Keith Donald
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.springframework.web.servlet.config.annotation;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -146,9 +147,18 @@ public class InterceptorConfigurerTests {
|
|||
private List<HandlerInterceptor> getInterceptorsForPath(String lookupPath) {
|
||||
PathMatcher pathMatcher = new AntPathMatcher();
|
||||
List<HandlerInterceptor> result = new ArrayList<HandlerInterceptor>();
|
||||
for (MappedInterceptor interceptor : configurer.getInterceptors()) {
|
||||
if (interceptor.matches(lookupPath, pathMatcher)) {
|
||||
result.add(interceptor.getInterceptor());
|
||||
for (Object i : configurer.getInterceptors()) {
|
||||
if (i instanceof MappedInterceptor) {
|
||||
MappedInterceptor mappedInterceptor = (MappedInterceptor) i;
|
||||
if (mappedInterceptor.matches(lookupPath, pathMatcher)) {
|
||||
result.add(mappedInterceptor.getInterceptor());
|
||||
}
|
||||
}
|
||||
else if (i instanceof HandlerInterceptor){
|
||||
result.add((HandlerInterceptor) i);
|
||||
}
|
||||
else {
|
||||
fail("Unexpected interceptor type: " + i.getClass().getName());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.springframework.web.servlet.config.annotation;
|
|||
|
||||
import static org.easymock.EasyMock.capture;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.isA;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
@ -126,7 +127,7 @@ public class WebMvcConfigurationTests {
|
|||
replay(configurer);
|
||||
|
||||
mvcConfiguration.setConfigurers(Arrays.asList(configurer));
|
||||
mvcConfiguration.validator();
|
||||
mvcConfiguration.mvcValidator();
|
||||
|
||||
verify(configurer);
|
||||
}
|
||||
|
@ -137,28 +138,25 @@ public class WebMvcConfigurationTests {
|
|||
replay(configurer);
|
||||
|
||||
mvcConfiguration.setConfigurers(Arrays.asList(configurer));
|
||||
mvcConfiguration.validator();
|
||||
mvcConfiguration.mvcValidator();
|
||||
|
||||
verify(configurer);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void handlerExceptionResolver() throws Exception {
|
||||
Capture<List<HttpMessageConverter<?>>> converters = new Capture<List<HttpMessageConverter<?>>>();
|
||||
Capture<List<HandlerExceptionResolver>> exceptionResolvers = new Capture<List<HandlerExceptionResolver>>();
|
||||
|
||||
configurer.configureMessageConverters(capture(converters));
|
||||
configurer.configureHandlerExceptionResolvers(capture(exceptionResolvers));
|
||||
configurer.configureMessageConverters(isA(List.class));
|
||||
configurer.configureHandlerExceptionResolvers(isA(List.class));
|
||||
replay(configurer);
|
||||
|
||||
mvcConfiguration.setConfigurers(Arrays.asList(configurer));
|
||||
mvcConfiguration.handlerExceptionResolver();
|
||||
List<HandlerExceptionResolver> actual = mvcConfiguration.handlerExceptionResolver().getExceptionResolvers();
|
||||
|
||||
assertEquals(3, exceptionResolvers.getValue().size());
|
||||
assertTrue(exceptionResolvers.getValue().get(0) instanceof ExceptionHandlerExceptionResolver);
|
||||
assertTrue(exceptionResolvers.getValue().get(1) instanceof ResponseStatusExceptionResolver);
|
||||
assertTrue(exceptionResolvers.getValue().get(2) instanceof DefaultHandlerExceptionResolver);
|
||||
assertTrue(converters.getValue().size() > 0);
|
||||
assertEquals(3, actual.size());
|
||||
assertTrue(actual.get(0) instanceof ExceptionHandlerExceptionResolver);
|
||||
assertTrue(actual.get(1) instanceof ResponseStatusExceptionResolver);
|
||||
assertTrue(actual.get(2) instanceof DefaultHandlerExceptionResolver);
|
||||
|
||||
verify(configurer);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue