1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.bremersee.exception.spring.boot.autoconfigure.servlet;
18
19 import java.util.List;
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.bremersee.exception.RestApiExceptionMapper;
23 import org.bremersee.exception.servlet.ApiExceptionResolver;
24 import org.bremersee.exception.servlet.HttpServletRequestIdProvider;
25 import org.bremersee.exception.spring.boot.autoconfigure.RestApiExceptionMapperBootProperties;
26 import org.springframework.beans.factory.ObjectProvider;
27 import org.springframework.boot.autoconfigure.AutoConfiguration;
28 import org.springframework.boot.autoconfigure.AutoConfigureAfter;
29 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
30 import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
31 import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
32 import org.springframework.boot.context.event.ApplicationReadyEvent;
33 import org.springframework.boot.context.properties.EnableConfigurationProperties;
34 import org.springframework.context.event.EventListener;
35 import org.springframework.util.Assert;
36 import org.springframework.util.ClassUtils;
37 import org.springframework.web.servlet.HandlerExceptionResolver;
38 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
39 import tools.jackson.databind.json.JsonMapper;
40 import tools.jackson.dataformat.xml.XmlMapper;
41
42
43
44
45 @ConditionalOnWebApplication(type = Type.SERVLET)
46 @ConditionalOnClass(name = {
47 "tools.jackson.databind.ObjectMapper",
48 "org.bremersee.exception.RestApiExceptionMapperProperties",
49 "org.bremersee.exception.servlet.ApiExceptionResolver"
50 })
51 @AutoConfigureAfter({
52 RestApiExceptionMapperForWebAutoConfiguration.class
53 })
54 @AutoConfiguration
55 @EnableConfigurationProperties({RestApiExceptionMapperBootProperties.class})
56 public class ApiExceptionResolverAutoConfiguration implements WebMvcConfigurer {
57
58 private static final Log log = LogFactory
59 .getLog(ApiExceptionResolverAutoConfiguration.class);
60
61 private final RestApiExceptionMapperBootProperties properties;
62
63 private final ApiExceptionResolver apiExceptionResolver;
64
65
66
67
68
69
70
71
72
73
74 public ApiExceptionResolverAutoConfiguration(
75 RestApiExceptionMapperBootProperties properties,
76 ObjectProvider<RestApiExceptionMapper> apiExceptionMapper,
77 ObjectProvider<JsonMapper.Builder> jsonMapperBuilderProvider,
78 ObjectProvider<XmlMapper.Builder> xmlMapperBuilderProvider,
79 ObjectProvider<HttpServletRequestIdProvider> restApiIdProvider) {
80
81 RestApiExceptionMapper mapper = apiExceptionMapper.getIfAvailable();
82 Assert.notNull(mapper, "Api exception resolver must be present.");
83 this.properties = properties;
84 this.apiExceptionResolver = new ApiExceptionResolver(
85 properties.getApiPaths(),
86 mapper,
87 jsonMapperBuilderProvider.getIfAvailable(),
88 xmlMapperBuilderProvider.getIfAvailable());
89 this.apiExceptionResolver.setRestApiExceptionIdProvider(restApiIdProvider.getIfAvailable());
90 }
91
92
93
94
95 @EventListener(ApplicationReadyEvent.class)
96 public void init() {
97 log.info(String.format("""
98
99 *********************************************************************************
100 * %s
101 *********************************************************************************
102 * apiPaths = %s
103 *********************************************************************************""",
104 ClassUtils.getUserClass(getClass()).getSimpleName(),
105 properties.getApiPaths()));
106 }
107
108 @Override
109 public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
110 log.info(String.format("Adding exception resolver [%s] to registry.",
111 ClassUtils.getUserClass(apiExceptionResolver).getSimpleName()));
112 exceptionResolvers.addFirst(apiExceptionResolver);
113 }
114
115 }