Search in sources :

Example 1 with ExceptionHandlerMethodResolver

use of org.springframework.web.method.annotation.ExceptionHandlerMethodResolver in project spring-framework by spring-projects.

the class RequestMappingHandlerAdapter method getExceptionHandlerMethod.

private InvocableHandlerMethod getExceptionHandlerMethod(Throwable ex, HandlerMethod handlerMethod) {
    Class<?> handlerType = handlerMethod.getBeanType();
    ExceptionHandlerMethodResolver resolver = this.exceptionHandlerCache.computeIfAbsent(handlerType, ExceptionHandlerMethodResolver::new);
    return Optional.ofNullable(resolver.resolveMethodByThrowable(ex)).map(method -> createHandlerMethod(handlerMethod.getBean(), method)).orElseGet(() -> this.exceptionHandlerAdviceCache.entrySet().stream().map(entry -> {
        if (entry.getKey().isApplicableToBeanType(handlerType)) {
            Method method = entry.getValue().resolveMethodByThrowable(ex);
            if (method != null) {
                Object bean = entry.getKey().resolveBean();
                return createHandlerMethod(bean, method);
            }
        }
        return null;
    }).filter(Objects::nonNull).findFirst().orElse(null));
}
Also used : InvocableHandlerMethod(org.springframework.web.reactive.result.method.InvocableHandlerMethod) HttpMessageReader(org.springframework.http.codec.HttpMessageReader) RequestMapping(org.springframework.web.bind.annotation.RequestMapping) BindingContext(org.springframework.web.reactive.BindingContext) MethodIntrospector.selectMethods(org.springframework.core.MethodIntrospector.selectMethods) Function(java.util.function.Function) HandlerMethodArgumentResolver(org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver) InitializingBean(org.springframework.beans.factory.InitializingBean) ArrayList(java.util.ArrayList) ServerWebExchange(org.springframework.web.server.ServerWebExchange) LinkedHashMap(java.util.LinkedHashMap) HandlerMethod(org.springframework.web.method.HandlerMethod) ModelAttribute(org.springframework.web.bind.annotation.ModelAttribute) ExceptionHandlerMethodResolver(org.springframework.web.method.annotation.ExceptionHandlerMethodResolver) Map(java.util.Map) ConfigurableApplicationContext(org.springframework.context.ConfigurableApplicationContext) DataBufferDecoder(org.springframework.core.codec.DataBufferDecoder) Method(java.lang.reflect.Method) ReactiveAdapterRegistry(org.springframework.core.ReactiveAdapterRegistry) HandlerAdapter(org.springframework.web.reactive.HandlerAdapter) WebBindingInitializer(org.springframework.web.bind.support.WebBindingInitializer) StringDecoder(org.springframework.core.codec.StringDecoder) AnnotationUtils(org.springframework.core.annotation.AnnotationUtils) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) SyncHandlerMethodArgumentResolver(org.springframework.web.reactive.result.method.SyncHandlerMethodArgumentResolver) Mono(reactor.core.publisher.Mono) ByteBufferDecoder(org.springframework.core.codec.ByteBufferDecoder) ApplicationContext(org.springframework.context.ApplicationContext) ByteArrayDecoder(org.springframework.core.codec.ByteArrayDecoder) HandlerResult(org.springframework.web.reactive.HandlerResult) DecoderHttpMessageReader(org.springframework.http.codec.DecoderHttpMessageReader) Objects(java.util.Objects) List(java.util.List) ReflectionUtils(org.springframework.util.ReflectionUtils) Optional(java.util.Optional) Log(org.apache.commons.logging.Log) LogFactory(org.apache.commons.logging.LogFactory) ControllerAdviceBean(org.springframework.web.method.ControllerAdviceBean) ConfigurableBeanFactory(org.springframework.beans.factory.config.ConfigurableBeanFactory) InitBinder(org.springframework.web.bind.annotation.InitBinder) SyncInvocableHandlerMethod(org.springframework.web.reactive.result.method.SyncInvocableHandlerMethod) ApplicationContextAware(org.springframework.context.ApplicationContextAware) AnnotationAwareOrderComparator(org.springframework.core.annotation.AnnotationAwareOrderComparator) Assert(org.springframework.util.Assert) ExceptionHandlerMethodResolver(org.springframework.web.method.annotation.ExceptionHandlerMethodResolver) InvocableHandlerMethod(org.springframework.web.reactive.result.method.InvocableHandlerMethod) HandlerMethod(org.springframework.web.method.HandlerMethod) Method(java.lang.reflect.Method) SyncInvocableHandlerMethod(org.springframework.web.reactive.result.method.SyncInvocableHandlerMethod)

Example 2 with ExceptionHandlerMethodResolver

use of org.springframework.web.method.annotation.ExceptionHandlerMethodResolver in project spring-framework by spring-projects.

the class RequestMappingHandlerAdapter method initControllerAdviceCache.

private void initControllerAdviceCache() {
    if (getApplicationContext() == null) {
        return;
    }
    if (logger.isInfoEnabled()) {
        logger.info("Looking for @ControllerAdvice: " + getApplicationContext());
    }
    List<ControllerAdviceBean> beans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
    AnnotationAwareOrderComparator.sort(beans);
    for (ControllerAdviceBean bean : beans) {
        Class<?> beanType = bean.getBeanType();
        Set<Method> attrMethods = selectMethods(beanType, ATTRIBUTE_METHODS);
        if (!attrMethods.isEmpty()) {
            this.attributeAdviceCache.put(bean, attrMethods);
            if (logger.isInfoEnabled()) {
                logger.info("Detected @ModelAttribute methods in " + bean);
            }
        }
        Set<Method> binderMethods = selectMethods(beanType, BINDER_METHODS);
        if (!binderMethods.isEmpty()) {
            this.binderAdviceCache.put(bean, binderMethods);
            if (logger.isInfoEnabled()) {
                logger.info("Detected @InitBinder methods in " + bean);
            }
        }
        ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(beanType);
        if (resolver.hasExceptionMappings()) {
            this.exceptionHandlerAdviceCache.put(bean, resolver);
            if (logger.isInfoEnabled()) {
                logger.info("Detected @ExceptionHandler methods in " + bean);
            }
        }
    }
}
Also used : ExceptionHandlerMethodResolver(org.springframework.web.method.annotation.ExceptionHandlerMethodResolver) InvocableHandlerMethod(org.springframework.web.reactive.result.method.InvocableHandlerMethod) HandlerMethod(org.springframework.web.method.HandlerMethod) Method(java.lang.reflect.Method) SyncInvocableHandlerMethod(org.springframework.web.reactive.result.method.SyncInvocableHandlerMethod) ControllerAdviceBean(org.springframework.web.method.ControllerAdviceBean)

Example 3 with ExceptionHandlerMethodResolver

use of org.springframework.web.method.annotation.ExceptionHandlerMethodResolver in project spring-framework by spring-projects.

the class ExceptionHandlerExceptionResolver method initExceptionHandlerAdviceCache.

private void initExceptionHandlerAdviceCache() {
    if (getApplicationContext() == null) {
        return;
    }
    List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
    for (ControllerAdviceBean adviceBean : adviceBeans) {
        Class<?> beanType = adviceBean.getBeanType();
        if (beanType == null) {
            throw new IllegalStateException("Unresolvable type for ControllerAdviceBean: " + adviceBean);
        }
        ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(beanType);
        if (resolver.hasExceptionMappings()) {
            this.exceptionHandlerAdviceCache.put(adviceBean, resolver);
        }
        if (ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
            this.responseBodyAdvice.add(adviceBean);
        }
    }
    if (logger.isDebugEnabled()) {
        int handlerSize = this.exceptionHandlerAdviceCache.size();
        int adviceSize = this.responseBodyAdvice.size();
        if (handlerSize == 0 && adviceSize == 0) {
            logger.debug("ControllerAdvice beans: none");
        } else {
            logger.debug("ControllerAdvice beans: " + handlerSize + " @ExceptionHandler, " + adviceSize + " ResponseBodyAdvice");
        }
    }
}
Also used : ExceptionHandlerMethodResolver(org.springframework.web.method.annotation.ExceptionHandlerMethodResolver) ControllerAdviceBean(org.springframework.web.method.ControllerAdviceBean)

Example 4 with ExceptionHandlerMethodResolver

use of org.springframework.web.method.annotation.ExceptionHandlerMethodResolver in project spring-framework by spring-projects.

the class ExceptionHandlerExceptionResolver method getExceptionHandlerMethod.

/**
 * Find an {@code @ExceptionHandler} method for the given exception. The default
 * implementation searches methods in the class hierarchy of the controller first
 * and if not found, it continues searching for additional {@code @ExceptionHandler}
 * methods assuming some {@linkplain ControllerAdvice @ControllerAdvice}
 * Spring-managed beans were detected.
 * @param handlerMethod the method where the exception was raised (may be {@code null})
 * @param exception the raised exception
 * @return a method to handle the exception, or {@code null} if none
 */
@Nullable
protected ServletInvocableHandlerMethod getExceptionHandlerMethod(@Nullable HandlerMethod handlerMethod, Exception exception) {
    Class<?> handlerType = null;
    if (handlerMethod != null) {
        // Local exception handler methods on the controller class itself.
        // To be invoked through the proxy, even in case of an interface-based proxy.
        handlerType = handlerMethod.getBeanType();
        ExceptionHandlerMethodResolver resolver = this.exceptionHandlerCache.computeIfAbsent(handlerType, ExceptionHandlerMethodResolver::new);
        Method method = resolver.resolveMethod(exception);
        if (method != null) {
            return new ServletInvocableHandlerMethod(handlerMethod.getBean(), method, this.applicationContext);
        }
        // and annotation presence), use target class instead of interface-based proxy.
        if (Proxy.isProxyClass(handlerType)) {
            handlerType = AopUtils.getTargetClass(handlerMethod.getBean());
        }
    }
    for (Map.Entry<ControllerAdviceBean, ExceptionHandlerMethodResolver> entry : this.exceptionHandlerAdviceCache.entrySet()) {
        ControllerAdviceBean advice = entry.getKey();
        if (advice.isApplicableToBeanType(handlerType)) {
            ExceptionHandlerMethodResolver resolver = entry.getValue();
            Method method = resolver.resolveMethod(exception);
            if (method != null) {
                return new ServletInvocableHandlerMethod(advice.resolveBean(), method, this.applicationContext);
            }
        }
    }
    return null;
}
Also used : ExceptionHandlerMethodResolver(org.springframework.web.method.annotation.ExceptionHandlerMethodResolver) HandlerMethod(org.springframework.web.method.HandlerMethod) Method(java.lang.reflect.Method) ModelMap(org.springframework.ui.ModelMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ControllerAdviceBean(org.springframework.web.method.ControllerAdviceBean) Nullable(org.springframework.lang.Nullable)

Example 5 with ExceptionHandlerMethodResolver

use of org.springframework.web.method.annotation.ExceptionHandlerMethodResolver in project entando-core by entando.

the class AbstractControllerTest method createExceptionResolver.

protected ExceptionHandlerExceptionResolver createExceptionResolver() {
    final ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    messageSource.setBasename("rest/messages");
    messageSource.setUseCodeAsDefaultMessage(true);
    ExceptionHandlerExceptionResolver exceptionResolver = new ExceptionHandlerExceptionResolver() {

        @Override
        protected ServletInvocableHandlerMethod getExceptionHandlerMethod(HandlerMethod handlerMethod, Exception exception) {
            Method method = new ExceptionHandlerMethodResolver(RestExceptionHandler.class).resolveMethod(exception);
            RestExceptionHandler validationHandler = new RestExceptionHandler();
            validationHandler.setMessageSource(messageSource);
            return new ServletInvocableHandlerMethod(validationHandler, method);
        }
    };
    exceptionResolver.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
    exceptionResolver.afterPropertiesSet();
    return exceptionResolver;
}
Also used : ExceptionHandlerExceptionResolver(org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver) MappingJackson2HttpMessageConverter(org.springframework.http.converter.json.MappingJackson2HttpMessageConverter) RestExceptionHandler(org.entando.entando.web.common.handlers.RestExceptionHandler) ServletInvocableHandlerMethod(org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod) ExceptionHandlerMethodResolver(org.springframework.web.method.annotation.ExceptionHandlerMethodResolver) ResourceBundleMessageSource(org.springframework.context.support.ResourceBundleMessageSource) ServletInvocableHandlerMethod(org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod) HandlerMethod(org.springframework.web.method.HandlerMethod) Method(java.lang.reflect.Method) ServletInvocableHandlerMethod(org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod) HandlerMethod(org.springframework.web.method.HandlerMethod) JsonParseException(com.fasterxml.jackson.core.JsonParseException) ApsSystemException(com.agiletec.aps.system.exception.ApsSystemException) IOException(java.io.IOException) JsonMappingException(com.fasterxml.jackson.databind.JsonMappingException)

Aggregations

ExceptionHandlerMethodResolver (org.springframework.web.method.annotation.ExceptionHandlerMethodResolver)8 Method (java.lang.reflect.Method)6 ControllerAdviceBean (org.springframework.web.method.ControllerAdviceBean)6 HandlerMethod (org.springframework.web.method.HandlerMethod)6 InvocableHandlerMethod (org.springframework.web.reactive.result.method.InvocableHandlerMethod)4 SyncInvocableHandlerMethod (org.springframework.web.reactive.result.method.SyncInvocableHandlerMethod)4 LinkedHashMap (java.util.LinkedHashMap)3 Map (java.util.Map)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 Nullable (org.springframework.lang.Nullable)2 ApsSystemException (com.agiletec.aps.system.exception.ApsSystemException)1 JsonParseException (com.fasterxml.jackson.core.JsonParseException)1 JsonMappingException (com.fasterxml.jackson.databind.JsonMappingException)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Objects (java.util.Objects)1 Optional (java.util.Optional)1 Set (java.util.Set)1 Function (java.util.function.Function)1