|
|
|
@ -1,5 +1,5 @@ |
|
|
|
/* |
|
|
|
/* |
|
|
|
* Copyright 2002-2013 the original author or authors. |
|
|
|
* Copyright 2002-2014 the original author or authors. |
|
|
|
* |
|
|
|
* |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
@ -28,7 +28,6 @@ import javax.servlet.http.HttpServletRequest; |
|
|
|
import javax.servlet.http.HttpServletResponse; |
|
|
|
import javax.servlet.http.HttpServletResponse; |
|
|
|
import javax.xml.transform.Source; |
|
|
|
import javax.xml.transform.Source; |
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.beans.BeansException; |
|
|
|
|
|
|
|
import org.springframework.beans.factory.InitializingBean; |
|
|
|
import org.springframework.beans.factory.InitializingBean; |
|
|
|
import org.springframework.context.ApplicationContext; |
|
|
|
import org.springframework.context.ApplicationContext; |
|
|
|
import org.springframework.context.ApplicationContextAware; |
|
|
|
import org.springframework.context.ApplicationContextAware; |
|
|
|
@ -68,34 +67,31 @@ import org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionRes |
|
|
|
* @author Rossen Stoyanchev |
|
|
|
* @author Rossen Stoyanchev |
|
|
|
* @since 3.1 |
|
|
|
* @since 3.1 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolver implements |
|
|
|
public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolver |
|
|
|
InitializingBean, ApplicationContextAware { |
|
|
|
implements ApplicationContextAware, InitializingBean { |
|
|
|
|
|
|
|
|
|
|
|
private List<HandlerMethodArgumentResolver> customArgumentResolvers; |
|
|
|
private List<HandlerMethodArgumentResolver> customArgumentResolvers; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private HandlerMethodArgumentResolverComposite argumentResolvers; |
|
|
|
|
|
|
|
|
|
|
|
private List<HandlerMethodReturnValueHandler> customReturnValueHandlers; |
|
|
|
private List<HandlerMethodReturnValueHandler> customReturnValueHandlers; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private HandlerMethodReturnValueHandlerComposite returnValueHandlers; |
|
|
|
|
|
|
|
|
|
|
|
private List<HttpMessageConverter<?>> messageConverters; |
|
|
|
private List<HttpMessageConverter<?>> messageConverters; |
|
|
|
|
|
|
|
|
|
|
|
private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager(); |
|
|
|
private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private ApplicationContext applicationContext; |
|
|
|
|
|
|
|
|
|
|
|
private final Map<Class<?>, ExceptionHandlerMethodResolver> exceptionHandlerCache = |
|
|
|
private final Map<Class<?>, ExceptionHandlerMethodResolver> exceptionHandlerCache = |
|
|
|
new ConcurrentHashMap<Class<?>, ExceptionHandlerMethodResolver>(64); |
|
|
|
new ConcurrentHashMap<Class<?>, ExceptionHandlerMethodResolver>(64); |
|
|
|
|
|
|
|
|
|
|
|
private final Map<ControllerAdviceBean, ExceptionHandlerMethodResolver> exceptionHandlerAdviceCache = |
|
|
|
private final Map<ControllerAdviceBean, ExceptionHandlerMethodResolver> exceptionHandlerAdviceCache = |
|
|
|
new LinkedHashMap<ControllerAdviceBean, ExceptionHandlerMethodResolver>(); |
|
|
|
new LinkedHashMap<ControllerAdviceBean, ExceptionHandlerMethodResolver>(); |
|
|
|
|
|
|
|
|
|
|
|
private HandlerMethodArgumentResolverComposite argumentResolvers; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private HandlerMethodReturnValueHandlerComposite returnValueHandlers; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private ApplicationContext applicationContext; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Default constructor. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public ExceptionHandlerExceptionResolver() { |
|
|
|
public ExceptionHandlerExceptionResolver() { |
|
|
|
|
|
|
|
|
|
|
|
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(); |
|
|
|
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(); |
|
|
|
stringHttpMessageConverter.setWriteAcceptCharset(false); // See SPR-7316
|
|
|
|
stringHttpMessageConverter.setWriteAcceptCharset(false); // See SPR-7316
|
|
|
|
|
|
|
|
|
|
|
|
@ -106,6 +102,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce |
|
|
|
this.messageConverters.add(new AllEncompassingFormHttpMessageConverter()); |
|
|
|
this.messageConverters.add(new AllEncompassingFormHttpMessageConverter()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Provide resolvers for custom argument types. Custom resolvers are ordered |
|
|
|
* Provide resolvers for custom argument types. Custom resolvers are ordered |
|
|
|
* after built-in ones. To override the built-in support for argument |
|
|
|
* after built-in ones. To override the built-in support for argument |
|
|
|
@ -194,7 +191,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce |
|
|
|
* Return the configured message body converters. |
|
|
|
* Return the configured message body converters. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public List<HttpMessageConverter<?>> getMessageConverters() { |
|
|
|
public List<HttpMessageConverter<?>> getMessageConverters() { |
|
|
|
return messageConverters; |
|
|
|
return this.messageConverters; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -223,7 +220,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { |
|
|
|
public void setApplicationContext(ApplicationContext applicationContext) { |
|
|
|
this.applicationContext = applicationContext; |
|
|
|
this.applicationContext = applicationContext; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -231,6 +228,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce |
|
|
|
return this.applicationContext; |
|
|
|
return this.applicationContext; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void afterPropertiesSet() { |
|
|
|
public void afterPropertiesSet() { |
|
|
|
if (this.argumentResolvers == null) { |
|
|
|
if (this.argumentResolvers == null) { |
|
|
|
@ -315,6 +313,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Find an {@code @ExceptionHandler} method and invoke it to handle the raised exception. |
|
|
|
* Find an {@code @ExceptionHandler} method and invoke it to handle the raised exception. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@ -340,7 +339,9 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce |
|
|
|
exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, exception); |
|
|
|
exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, exception); |
|
|
|
} |
|
|
|
} |
|
|
|
catch (Exception invocationEx) { |
|
|
|
catch (Exception invocationEx) { |
|
|
|
|
|
|
|
if (logger.isErrorEnabled()) { |
|
|
|
logger.error("Failed to invoke @ExceptionHandler method: " + exceptionHandlerMethod, invocationEx); |
|
|
|
logger.error("Failed to invoke @ExceptionHandler method: " + exceptionHandlerMethod, invocationEx); |
|
|
|
|
|
|
|
} |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -363,12 +364,13 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce |
|
|
|
* and if not found, it continues searching for additional {@code @ExceptionHandler} |
|
|
|
* and if not found, it continues searching for additional {@code @ExceptionHandler} |
|
|
|
* methods assuming some {@linkplain ControllerAdvice @ControllerAdvice} |
|
|
|
* methods assuming some {@linkplain ControllerAdvice @ControllerAdvice} |
|
|
|
* Spring-managed beans were detected. |
|
|
|
* Spring-managed beans were detected. |
|
|
|
* @param handlerMethod the method where the exception was raised, possibly {@code null} |
|
|
|
* @param handlerMethod the method where the exception was raised (may be {@code null}) |
|
|
|
* @param exception the raised exception |
|
|
|
* @param exception the raised exception |
|
|
|
* @return a method to handle the exception, or {@code null} |
|
|
|
* @return a method to handle the exception, or {@code null} |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected ServletInvocableHandlerMethod getExceptionHandlerMethod(HandlerMethod handlerMethod, Exception exception) { |
|
|
|
protected ServletInvocableHandlerMethod getExceptionHandlerMethod(HandlerMethod handlerMethod, Exception exception) { |
|
|
|
Class<?> handlerType = (handlerMethod != null) ? handlerMethod.getBeanType() : null; |
|
|
|
Class<?> handlerType = (handlerMethod != null ? handlerMethod.getBeanType() : null); |
|
|
|
|
|
|
|
|
|
|
|
if (handlerMethod != null) { |
|
|
|
if (handlerMethod != null) { |
|
|
|
ExceptionHandlerMethodResolver resolver = this.exceptionHandlerCache.get(handlerType); |
|
|
|
ExceptionHandlerMethodResolver resolver = this.exceptionHandlerCache.get(handlerType); |
|
|
|
if (resolver == null) { |
|
|
|
if (resolver == null) { |
|
|
|
@ -380,6 +382,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce |
|
|
|
return new ServletInvocableHandlerMethod(handlerMethod.getBean(), method); |
|
|
|
return new ServletInvocableHandlerMethod(handlerMethod.getBean(), method); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (Entry<ControllerAdviceBean, ExceptionHandlerMethodResolver> entry : this.exceptionHandlerAdviceCache.entrySet()) { |
|
|
|
for (Entry<ControllerAdviceBean, ExceptionHandlerMethodResolver> entry : this.exceptionHandlerAdviceCache.entrySet()) { |
|
|
|
if (entry.getKey().isApplicableToBeanType(handlerType)) { |
|
|
|
if (entry.getKey().isApplicableToBeanType(handlerType)) { |
|
|
|
ExceptionHandlerMethodResolver resolver = entry.getValue(); |
|
|
|
ExceptionHandlerMethodResolver resolver = entry.getValue(); |
|
|
|
@ -389,6 +392,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|