CompositeExceptionResolverFactoryBean.java

  1. package cn.home1.oss.lib.errorhandle.starter;

  2. import com.google.common.collect.ImmutableMap;

  3. import cn.home1.oss.lib.errorhandle.api.ApplicationException;
  4. import cn.home1.oss.lib.errorhandle.api.ConcreteExceptionResolver;
  5. import cn.home1.oss.lib.errorhandle.api.ExceptionResolver;
  6. import cn.home1.oss.lib.errorhandle.api.ExceptionTranslator;
  7. import cn.home1.oss.lib.errorhandle.api.StackTraceIndicator;
  8. import cn.home1.oss.lib.errorhandle.internal.CompositeExceptionResolver;
  9. import cn.home1.oss.lib.errorhandle.internal.resolver.ApplicationErrorExceptionResolver;
  10. import cn.home1.oss.lib.errorhandle.internal.resolver.ConstraintViolationExceptionResolver;
  11. import cn.home1.oss.lib.errorhandle.internal.resolver.DefaultExceptionResolver;
  12. import cn.home1.oss.lib.errorhandle.internal.resolver.HttpMediaTypeNotSupportedExceptionResolver;
  13. import cn.home1.oss.lib.errorhandle.internal.resolver.HttpRequestMethodNotSupportedExceptionResolver;
  14. import cn.home1.oss.lib.errorhandle.internal.resolver.MethodArgumentNotValidExceptionResolver;

  15. import lombok.Setter;
  16. import lombok.extern.slf4j.Slf4j;

  17. import org.springframework.beans.factory.FactoryBean;
  18. import org.springframework.beans.factory.annotation.Autowired;
  19. import org.springframework.core.convert.ConversionService;
  20. import org.springframework.core.convert.support.DefaultConversionService;
  21. import org.springframework.util.ClassUtils;
  22. import org.springframework.web.HttpMediaTypeNotSupportedException;
  23. import org.springframework.web.HttpRequestMethodNotSupportedException;
  24. import org.springframework.web.bind.MethodArgumentNotValidException;

  25. import java.util.Map;

  26. @Setter
  27. @Slf4j
  28. public class CompositeExceptionResolverFactoryBean implements FactoryBean<ExceptionResolver<Throwable>> {

  29.   public static final String CONSTRAINT_VIOLATION_EXCEPTION = "javax.validation.ConstraintViolationException";

  30.   @Autowired
  31.   private ExceptionTranslator exceptionTranslator;
  32.   @Autowired
  33.   private StackTraceIndicator stackTraceIndicator;

  34.   @SuppressWarnings({"rawtypes", "unchecked"})
  35.   static Map<Class<? extends Throwable>, ConcreteExceptionResolver> buildInResolvers( //
  36.     final ConversionService conversionService, //
  37.     final ExceptionTranslator exceptionTranslator, //
  38.     final StackTraceIndicator stackTraceIndicator //
  39.   ) {
  40.     final ImmutableMap.Builder<Class<? extends Throwable>, ConcreteExceptionResolver> builder = ImmutableMap.builder();

  41.     if (ClassUtils.isPresent( //
  42.       CONSTRAINT_VIOLATION_EXCEPTION, //
  43.       Thread.currentThread().getContextClassLoader() //
  44.     )) {
  45.       try {
  46.         final Class clazz = Class.forName(CONSTRAINT_VIOLATION_EXCEPTION);
  47.         builder.put(clazz, new ConstraintViolationExceptionResolver());
  48.       } catch (final ClassNotFoundException ex) {
  49.         // ignore
  50.         if (log.isDebugEnabled()) {
  51.           log.debug("class {} not found", CONSTRAINT_VIOLATION_EXCEPTION, ex);
  52.         }
  53.       }
  54.     }

  55.     builder.put(HttpMediaTypeNotSupportedException.class, new HttpMediaTypeNotSupportedExceptionResolver());
  56.     builder.put(HttpRequestMethodNotSupportedException.class, new HttpRequestMethodNotSupportedExceptionResolver());
  57.     builder.put(MethodArgumentNotValidException.class, new MethodArgumentNotValidExceptionResolver());
  58.     builder.put(ApplicationException.class, new ApplicationErrorExceptionResolver());

  59.     final Map<Class<? extends Throwable>, ConcreteExceptionResolver> map = builder.build();
  60.     map.values().forEach(exceptionResolver -> {
  61.       exceptionResolver.setConversionService(conversionService);
  62.       exceptionResolver.setExceptionTranslator(exceptionTranslator);
  63.       exceptionResolver.setStackTraceIndicator(stackTraceIndicator);
  64.     });

  65.     return map;
  66.   }

  67.   @Override
  68.   public ExceptionResolver<Throwable> getObject() {
  69.     final ConversionService conversionService = new DefaultConversionService(); // TODO conversionService

  70.     @SuppressWarnings("rawtypes")
  71.     final Map<Class<? extends Throwable>, ConcreteExceptionResolver> buildInResolvers = buildInResolvers( //
  72.       conversionService, //
  73.       this.exceptionTranslator, //
  74.       this.stackTraceIndicator //
  75.     );

  76.     final DefaultExceptionResolver defaultResolver = new DefaultExceptionResolver();
  77.     defaultResolver.setConversionService(conversionService);
  78.     defaultResolver.setExceptionTranslator(this.exceptionTranslator);
  79.     defaultResolver.setStackTraceIndicator(this.stackTraceIndicator);

  80.     final CompositeExceptionResolver compositeExceptionResolver = new CompositeExceptionResolver();
  81.     compositeExceptionResolver.setDefaultResolver(defaultResolver);
  82.     compositeExceptionResolver.setResolverMap(buildInResolvers);

  83.     return compositeExceptionResolver;
  84.   }

  85.   @Override
  86.   public Class<?> getObjectType() {
  87.     return ExceptionResolver.class;
  88.   }

  89.   @Override
  90.   public boolean isSingleton() {
  91.     return false;
  92.   }
  93. }