Resolve custom args after annotated args, set PATH_WITHIN_HANDLER_MAPPING attribute, and rename resolver for @ExceptionHandler methods
This commit is contained in:
parent
50117dce40
commit
c91ab1ad6e
|
|
@ -42,7 +42,7 @@ import org.springframework.web.servlet.handler.ConversionServiceExposingIntercep
|
|||
import org.springframework.web.servlet.handler.MappedInterceptor;
|
||||
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodAdapter;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodExceptionResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodMapping;
|
||||
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
||||
|
||||
|
|
@ -118,7 +118,7 @@ final class MvcAnnotationDrivenExecutor extends AbstractSpecificationExecutor<Mv
|
|||
String mappedInterceptorName = registrar.registerWithGeneratedName(mappedCsInterceptorDef);
|
||||
|
||||
RootBeanDefinition methodExceptionResolver = new RootBeanDefinition(
|
||||
RequestMappingHandlerMethodExceptionResolver.class);
|
||||
ExceptionHandlerExceptionResolver.class);
|
||||
methodExceptionResolver.setSource(source);
|
||||
methodExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
methodExceptionResolver.getPropertyValues().add("messageConverters", messageConverters);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import org.springframework.util.MultiValueMap;
|
|||
import org.springframework.util.ReflectionUtils.MethodFilter;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.method.HandlerMethodSelector;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.util.UrlPathHelper;
|
||||
|
||||
/**
|
||||
|
|
@ -272,6 +273,7 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
|
|||
* @param request the current request
|
||||
*/
|
||||
protected void handleMatch(T mapping, String lookupPath, HttpServletRequest request) {
|
||||
request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, lookupPath);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ import org.springframework.web.servlet.mvc.method.annotation.support.ViewMethodR
|
|||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
*/
|
||||
public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandlerMethodExceptionResolver implements
|
||||
public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolver implements
|
||||
InitializingBean {
|
||||
|
||||
private List<HandlerMethodArgumentResolver> customArgumentResolvers;
|
||||
|
|
@ -96,9 +96,9 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
|
|||
private HandlerMethodReturnValueHandlerComposite returnValueHandlers;
|
||||
|
||||
/**
|
||||
* Creates an instance of {@link RequestMappingHandlerMethodExceptionResolver}.
|
||||
* Creates an instance of {@link ExceptionHandlerExceptionResolver}.
|
||||
*/
|
||||
public RequestMappingHandlerMethodExceptionResolver() {
|
||||
public ExceptionHandlerExceptionResolver() {
|
||||
|
||||
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
|
||||
stringHttpMessageConverter.setWriteAcceptCharset(false); // See SPR-7316
|
||||
|
|
@ -331,95 +331,84 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
|
|||
}
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
initArgumentResolvers();
|
||||
initReturnValueHandlers();
|
||||
initInitBinderArgumentResolvers();
|
||||
}
|
||||
|
||||
private void initArgumentResolvers() {
|
||||
if (argumentResolvers == null) {
|
||||
argumentResolvers = new HandlerMethodArgumentResolverComposite();
|
||||
}
|
||||
|
||||
// Annotation-based resolvers
|
||||
argumentResolvers.addResolver(new RequestParamMethodArgumentResolver(beanFactory, false));
|
||||
argumentResolvers.addResolver(new RequestParamMapMethodArgumentResolver());
|
||||
argumentResolvers.addResolver(new PathVariableMethodArgumentResolver());
|
||||
argumentResolvers.addResolver(new ServletModelAttributeMethodProcessor(false));
|
||||
argumentResolvers.addResolver(new RequestResponseBodyMethodProcessor(messageConverters));
|
||||
argumentResolvers.addResolver(new RequestHeaderMethodArgumentResolver(beanFactory));
|
||||
argumentResolvers.addResolver(new RequestHeaderMapMethodArgumentResolver());
|
||||
argumentResolvers.addResolver(new ServletCookieValueMethodArgumentResolver(beanFactory));
|
||||
argumentResolvers.addResolver(new ExpressionValueMethodArgumentResolver(beanFactory));
|
||||
|
||||
// Custom resolvers
|
||||
argumentResolvers.addResolvers(customArgumentResolvers);
|
||||
argumentResolvers.addResolvers(getDefaultArgumentResolvers(messageConverters, beanFactory));
|
||||
}
|
||||
|
||||
if (returnValueHandlers == null) {
|
||||
returnValueHandlers = new HandlerMethodReturnValueHandlerComposite();
|
||||
returnValueHandlers.addHandlers(customReturnValueHandlers);
|
||||
returnValueHandlers.addHandlers(getDefaultReturnValueHandlers(messageConverters, modelAndViewResolvers));
|
||||
|
||||
// Type-based resolvers
|
||||
argumentResolvers.addResolver(new ServletRequestMethodArgumentResolver());
|
||||
argumentResolvers.addResolver(new ServletResponseMethodArgumentResolver());
|
||||
argumentResolvers.addResolver(new HttpEntityMethodProcessor(messageConverters));
|
||||
argumentResolvers.addResolver(new ModelMethodProcessor());
|
||||
argumentResolvers.addResolver(new ErrorsMethodArgumentResolver());
|
||||
|
||||
// Default-mode resolution
|
||||
argumentResolvers.addResolver(new RequestParamMethodArgumentResolver(beanFactory, true));
|
||||
argumentResolvers.addResolver(new ServletModelAttributeMethodProcessor(true));
|
||||
}
|
||||
|
||||
private void initInitBinderArgumentResolvers() {
|
||||
if (initBinderArgumentResolvers == null) {
|
||||
initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite();
|
||||
initBinderArgumentResolvers.addResolvers(customArgumentResolvers);
|
||||
initBinderArgumentResolvers.addResolvers(getDefaultInitBinderArgumentResolvers(beanFactory));
|
||||
}
|
||||
}
|
||||
|
||||
public static List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers(
|
||||
List<HttpMessageConverter<?>> messageConverters, ConfigurableBeanFactory beanFactory) {
|
||||
|
||||
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>();
|
||||
|
||||
// Annotation-based resolvers
|
||||
resolvers.add(new RequestParamMethodArgumentResolver(beanFactory, false));
|
||||
resolvers.add(new RequestParamMapMethodArgumentResolver());
|
||||
resolvers.add(new PathVariableMethodArgumentResolver());
|
||||
resolvers.add(new ServletModelAttributeMethodProcessor(false));
|
||||
resolvers.add(new RequestResponseBodyMethodProcessor(messageConverters));
|
||||
resolvers.add(new RequestHeaderMethodArgumentResolver(beanFactory));
|
||||
resolvers.add(new RequestHeaderMapMethodArgumentResolver());
|
||||
resolvers.add(new ServletCookieValueMethodArgumentResolver(beanFactory));
|
||||
resolvers.add(new ExpressionValueMethodArgumentResolver(beanFactory));
|
||||
initBinderArgumentResolvers.addResolver(new RequestParamMethodArgumentResolver(beanFactory, false));
|
||||
initBinderArgumentResolvers.addResolver(new RequestParamMapMethodArgumentResolver());
|
||||
initBinderArgumentResolvers.addResolver(new PathVariableMethodArgumentResolver());
|
||||
initBinderArgumentResolvers.addResolver(new ExpressionValueMethodArgumentResolver(beanFactory));
|
||||
|
||||
// Custom resolvers
|
||||
argumentResolvers.addResolvers(customArgumentResolvers);
|
||||
|
||||
// Type-based resolvers
|
||||
resolvers.add(new ServletRequestMethodArgumentResolver());
|
||||
resolvers.add(new ServletResponseMethodArgumentResolver());
|
||||
resolvers.add(new HttpEntityMethodProcessor(messageConverters));
|
||||
resolvers.add(new ModelMethodProcessor());
|
||||
resolvers.add(new ErrorsMethodArgumentResolver());
|
||||
initBinderArgumentResolvers.addResolver(new ServletRequestMethodArgumentResolver());
|
||||
initBinderArgumentResolvers.addResolver(new ServletResponseMethodArgumentResolver());
|
||||
|
||||
// Default-mode resolution
|
||||
resolvers.add(new RequestParamMethodArgumentResolver(beanFactory, true));
|
||||
resolvers.add(new ServletModelAttributeMethodProcessor(true));
|
||||
|
||||
return resolvers;
|
||||
initBinderArgumentResolvers.addResolver(new RequestParamMethodArgumentResolver(beanFactory, true));
|
||||
}
|
||||
|
||||
public static List<HandlerMethodArgumentResolver> getDefaultInitBinderArgumentResolvers(
|
||||
ConfigurableBeanFactory beanFactory) {
|
||||
|
||||
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>();
|
||||
|
||||
// Annotation-based resolvers
|
||||
resolvers.add(new RequestParamMethodArgumentResolver(beanFactory, false));
|
||||
resolvers.add(new RequestParamMapMethodArgumentResolver());
|
||||
resolvers.add(new PathVariableMethodArgumentResolver());
|
||||
resolvers.add(new ExpressionValueMethodArgumentResolver(beanFactory));
|
||||
|
||||
// Type-based resolvers
|
||||
resolvers.add(new ServletRequestMethodArgumentResolver());
|
||||
resolvers.add(new ServletResponseMethodArgumentResolver());
|
||||
|
||||
// Default-mode resolution
|
||||
resolvers.add(new RequestParamMethodArgumentResolver(beanFactory, true));
|
||||
|
||||
return resolvers;
|
||||
private void initReturnValueHandlers() {
|
||||
if (returnValueHandlers == null) {
|
||||
returnValueHandlers = new HandlerMethodReturnValueHandlerComposite();
|
||||
}
|
||||
|
||||
public static List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers(
|
||||
List<HttpMessageConverter<?>> messageConverters, List<ModelAndViewResolver> modelAndViewResolvers) {
|
||||
|
||||
List<HandlerMethodReturnValueHandler> handlers = new ArrayList<HandlerMethodReturnValueHandler>();
|
||||
|
||||
// Annotation-based handlers
|
||||
handlers.add(new RequestResponseBodyMethodProcessor(messageConverters));
|
||||
handlers.add(new ModelAttributeMethodProcessor(false));
|
||||
returnValueHandlers.addHandler(new RequestResponseBodyMethodProcessor(messageConverters));
|
||||
returnValueHandlers.addHandler(new ModelAttributeMethodProcessor(false));
|
||||
|
||||
// Custom return value handlers
|
||||
returnValueHandlers.addHandlers(customReturnValueHandlers);
|
||||
|
||||
// Type-based handlers
|
||||
handlers.add(new ModelAndViewMethodReturnValueHandler());
|
||||
handlers.add(new ModelMethodProcessor());
|
||||
handlers.add(new ViewMethodReturnValueHandler());
|
||||
handlers.add(new HttpEntityMethodProcessor(messageConverters));
|
||||
returnValueHandlers.addHandler(new ModelAndViewMethodReturnValueHandler());
|
||||
returnValueHandlers.addHandler(new ModelMethodProcessor());
|
||||
returnValueHandlers.addHandler(new ViewMethodReturnValueHandler());
|
||||
returnValueHandlers.addHandler(new HttpEntityMethodProcessor(messageConverters));
|
||||
|
||||
// Default handler
|
||||
handlers.add(new DefaultMethodReturnValueHandler(modelAndViewResolvers));
|
||||
|
||||
return handlers;
|
||||
returnValueHandlers.addHandler(new DefaultMethodReturnValueHandler(modelAndViewResolvers));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ public class RequestMappingHandlerMethodMapping extends AbstractHandlerMethodMap
|
|||
|
||||
@Override
|
||||
protected void handleMatch(RequestMappingInfo mapping, String lookupPath, HttpServletRequest request) {
|
||||
super.handleMatch(mapping, lookupPath, request);
|
||||
String pattern = mapping.getPatterns().iterator().next();
|
||||
Map<String, String> uriTemplateVariables = pathMatcher.extractUriTemplateVariables(pattern, lookupPath);
|
||||
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVariables);
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ import org.springframework.web.context.support.GenericWebApplicationContext;
|
|||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodAdapter;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodExceptionResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebArgumentResolverAdapter;
|
||||
|
||||
/**
|
||||
|
|
@ -71,14 +71,14 @@ public class AnnotationDrivenBeanDefinitionParserTests {
|
|||
public void testMessageConverters() {
|
||||
loadBeanDefinitions("mvc-config-message-converters.xml");
|
||||
verifyMessageConverters(appContext.getBean(RequestMappingHandlerMethodAdapter.class), true);
|
||||
verifyMessageConverters(appContext.getBean(RequestMappingHandlerMethodExceptionResolver.class), true);
|
||||
verifyMessageConverters(appContext.getBean(ExceptionHandlerExceptionResolver.class), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageConvertersWithoutDefaultRegistrations() {
|
||||
loadBeanDefinitions("mvc-config-message-converters-defaults-off.xml");
|
||||
verifyMessageConverters(appContext.getBean(RequestMappingHandlerMethodAdapter.class), false);
|
||||
verifyMessageConverters(appContext.getBean(RequestMappingHandlerMethodExceptionResolver.class), false);
|
||||
verifyMessageConverters(appContext.getBean(ExceptionHandlerExceptionResolver.class), false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
|
|||
|
|
@ -43,18 +43,18 @@ import org.springframework.web.bind.annotation.ResponseStatus;
|
|||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.method.support.InvocableHandlerMethod;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodExceptionResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
||||
|
||||
/**
|
||||
* Test fixture with {@link RequestMappingHandlerMethodExceptionResolver}.
|
||||
* Test fixture with {@link ExceptionHandlerExceptionResolver}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.1
|
||||
*/
|
||||
public class RequestMappingHandlerMethodExceptionResolverTests {
|
||||
public class ExceptionHandlerExceptionResolverTests {
|
||||
|
||||
private RequestMappingHandlerMethodExceptionResolver exceptionResolver;
|
||||
private ExceptionHandlerExceptionResolver exceptionResolver;
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ public class RequestMappingHandlerMethodExceptionResolverTests {
|
|||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
exceptionResolver = new RequestMappingHandlerMethodExceptionResolver();
|
||||
exceptionResolver = new ExceptionHandlerExceptionResolver();
|
||||
exceptionResolver.afterPropertiesSet();
|
||||
request = new MockHttpServletRequest();
|
||||
response = new MockHttpServletResponse();
|
||||
|
|
@ -2636,7 +2636,7 @@ public class ServletHandlerMethodTests {
|
|||
Class<?> adapterType = RequestMappingHandlerMethodAdapter.class;
|
||||
wac.registerBeanDefinition("handlerAdapter", new RootBeanDefinition(adapterType));
|
||||
|
||||
Class<?> resolverType = RequestMappingHandlerMethodExceptionResolver.class;
|
||||
Class<?> resolverType = ExceptionHandlerExceptionResolver.class;
|
||||
wac.registerBeanDefinition("requestMappingResolver", new RootBeanDefinition(resolverType));
|
||||
|
||||
resolverType = ResponseStatusExceptionResolver.class;
|
||||
|
|
|
|||
|
|
@ -607,7 +607,7 @@ public class UriTemplateServletHandlerMethodTests {
|
|||
Class<?> adapterType = RequestMappingHandlerMethodAdapter.class;
|
||||
wac.registerBeanDefinition("handlerAdapter", new RootBeanDefinition(adapterType));
|
||||
|
||||
Class<?> resolverType = RequestMappingHandlerMethodExceptionResolver.class;
|
||||
Class<?> resolverType = ExceptionHandlerExceptionResolver.class;
|
||||
wac.registerBeanDefinition("requestMappingResolver", new RootBeanDefinition(resolverType));
|
||||
|
||||
resolverType = ResponseStatusExceptionResolver.class;
|
||||
|
|
|
|||
Loading…
Reference in New Issue