1 package cn.home1.oss.lib.errorhandle.starter;
2
3 import com.google.common.collect.ImmutableMap;
4
5 import cn.home1.oss.lib.errorhandle.api.ApplicationException;
6 import cn.home1.oss.lib.errorhandle.api.ConcreteExceptionResolver;
7 import cn.home1.oss.lib.errorhandle.api.ExceptionResolver;
8 import cn.home1.oss.lib.errorhandle.api.ExceptionTranslator;
9 import cn.home1.oss.lib.errorhandle.api.StackTraceIndicator;
10 import cn.home1.oss.lib.errorhandle.internal.CompositeExceptionResolver;
11 import cn.home1.oss.lib.errorhandle.internal.resolver.ApplicationErrorExceptionResolver;
12 import cn.home1.oss.lib.errorhandle.internal.resolver.ConstraintViolationExceptionResolver;
13 import cn.home1.oss.lib.errorhandle.internal.resolver.DefaultExceptionResolver;
14 import cn.home1.oss.lib.errorhandle.internal.resolver.HttpMediaTypeNotSupportedExceptionResolver;
15 import cn.home1.oss.lib.errorhandle.internal.resolver.HttpRequestMethodNotSupportedExceptionResolver;
16 import cn.home1.oss.lib.errorhandle.internal.resolver.MethodArgumentNotValidExceptionResolver;
17
18 import lombok.Setter;
19 import lombok.extern.slf4j.Slf4j;
20
21 import org.springframework.beans.factory.FactoryBean;
22 import org.springframework.beans.factory.annotation.Autowired;
23 import org.springframework.core.convert.ConversionService;
24 import org.springframework.core.convert.support.DefaultConversionService;
25 import org.springframework.util.ClassUtils;
26 import org.springframework.web.HttpMediaTypeNotSupportedException;
27 import org.springframework.web.HttpRequestMethodNotSupportedException;
28 import org.springframework.web.bind.MethodArgumentNotValidException;
29
30 import java.util.Map;
31
32 @Setter
33 @Slf4j
34 public class CompositeExceptionResolverFactoryBean implements FactoryBean<ExceptionResolver<Throwable>> {
35
36 public static final String CONSTRAINT_VIOLATION_EXCEPTION = "javax.validation.ConstraintViolationException";
37
38 @Autowired
39 private ExceptionTranslator exceptionTranslator;
40 @Autowired
41 private StackTraceIndicator stackTraceIndicator;
42
43 @SuppressWarnings({"rawtypes", "unchecked"})
44 static Map<Class<? extends Throwable>, ConcreteExceptionResolver> buildInResolvers(
45 final ConversionService conversionService,
46 final ExceptionTranslator exceptionTranslator,
47 final StackTraceIndicator stackTraceIndicator
48 ) {
49 final ImmutableMap.Builder<Class<? extends Throwable>, ConcreteExceptionResolver> builder = ImmutableMap.builder();
50
51 if (ClassUtils.isPresent(
52 CONSTRAINT_VIOLATION_EXCEPTION,
53 Thread.currentThread().getContextClassLoader()
54 )) {
55 try {
56 final Class clazz = Class.forName(CONSTRAINT_VIOLATION_EXCEPTION);
57 builder.put(clazz, new ConstraintViolationExceptionResolver());
58 } catch (final ClassNotFoundException ex) {
59
60 if (log.isDebugEnabled()) {
61 log.debug("class {} not found", CONSTRAINT_VIOLATION_EXCEPTION, ex);
62 }
63 }
64 }
65
66 builder.put(HttpMediaTypeNotSupportedException.class, new HttpMediaTypeNotSupportedExceptionResolver());
67 builder.put(HttpRequestMethodNotSupportedException.class, new HttpRequestMethodNotSupportedExceptionResolver());
68 builder.put(MethodArgumentNotValidException.class, new MethodArgumentNotValidExceptionResolver());
69 builder.put(ApplicationException.class, new ApplicationErrorExceptionResolver());
70
71 final Map<Class<? extends Throwable>, ConcreteExceptionResolver> map = builder.build();
72 map.values().forEach(exceptionResolver -> {
73 exceptionResolver.setConversionService(conversionService);
74 exceptionResolver.setExceptionTranslator(exceptionTranslator);
75 exceptionResolver.setStackTraceIndicator(stackTraceIndicator);
76 });
77
78 return map;
79 }
80
81 @Override
82 public ExceptionResolver<Throwable> getObject() {
83 final ConversionService conversionService = new DefaultConversionService();
84
85 @SuppressWarnings("rawtypes")
86 final Map<Class<? extends Throwable>, ConcreteExceptionResolver> buildInResolvers = buildInResolvers(
87 conversionService,
88 this.exceptionTranslator,
89 this.stackTraceIndicator
90 );
91
92 final DefaultExceptionResolver defaultResolver = new DefaultExceptionResolver();
93 defaultResolver.setConversionService(conversionService);
94 defaultResolver.setExceptionTranslator(this.exceptionTranslator);
95 defaultResolver.setStackTraceIndicator(this.stackTraceIndicator);
96
97 final CompositeExceptionResolver compositeExceptionResolver = new CompositeExceptionResolver();
98 compositeExceptionResolver.setDefaultResolver(defaultResolver);
99 compositeExceptionResolver.setResolverMap(buildInResolvers);
100
101 return compositeExceptionResolver;
102 }
103
104 @Override
105 public Class<?> getObjectType() {
106 return ExceptionResolver.class;
107 }
108
109 @Override
110 public boolean isSingleton() {
111 return false;
112 }
113 }