16
16
17
17
package org .springframework .boot .autoconfigure .jersey ;
18
18
19
- import java .util .Arrays ;
20
- import java .util .EnumSet ;
21
- import java .util .List ;
22
- import java .util .Map .Entry ;
23
-
24
- import javax .annotation .PostConstruct ;
25
- import javax .servlet .DispatcherType ;
26
- import javax .servlet .ServletContext ;
27
- import javax .servlet .ServletException ;
28
- import javax .servlet .ServletRegistration ;
29
- import javax .ws .rs .ApplicationPath ;
30
- import javax .ws .rs .ext .ContextResolver ;
31
-
32
19
import com .fasterxml .jackson .databind .AnnotationIntrospector ;
33
20
import com .fasterxml .jackson .databind .ObjectMapper ;
34
21
import com .fasterxml .jackson .databind .cfg .MapperConfig ;
38
25
import org .glassfish .jersey .CommonProperties ;
39
26
import org .glassfish .jersey .jackson .JacksonFeature ;
40
27
import org .glassfish .jersey .server .ResourceConfig ;
28
+ import org .glassfish .jersey .server .internal .routing .UriRoutingContext ;
41
29
import org .glassfish .jersey .servlet .ServletContainer ;
42
30
import org .glassfish .jersey .servlet .ServletProperties ;
43
-
31
+ import org . glassfish . jersey . uri . UriTemplate ;
44
32
import org .springframework .beans .factory .ObjectProvider ;
45
33
import org .springframework .boot .autoconfigure .AutoConfigureAfter ;
46
34
import org .springframework .boot .autoconfigure .AutoConfigureBefore ;
47
35
import org .springframework .boot .autoconfigure .AutoConfigureOrder ;
48
36
import org .springframework .boot .autoconfigure .EnableAutoConfiguration ;
49
- import org .springframework .boot .autoconfigure .condition .ConditionalOnBean ;
50
- import org .springframework .boot .autoconfigure .condition .ConditionalOnClass ;
51
- import org .springframework .boot .autoconfigure .condition .ConditionalOnMissingBean ;
52
- import org .springframework .boot .autoconfigure .condition .ConditionalOnProperty ;
53
- import org .springframework .boot .autoconfigure .condition .ConditionalOnSingleCandidate ;
54
- import org .springframework .boot .autoconfigure .condition .ConditionalOnWebApplication ;
37
+ import org .springframework .boot .autoconfigure .condition .*;
55
38
import org .springframework .boot .autoconfigure .jackson .JacksonAutoConfiguration ;
56
39
import org .springframework .boot .autoconfigure .web .DispatcherServletAutoConfiguration ;
57
40
import org .springframework .boot .context .properties .EnableConfigurationProperties ;
70
53
import org .springframework .web .context .ServletContextAware ;
71
54
import org .springframework .web .filter .RequestContextFilter ;
72
55
56
+ import javax .annotation .PostConstruct ;
57
+ import javax .servlet .DispatcherType ;
58
+ import javax .servlet .ServletContext ;
59
+ import javax .servlet .ServletException ;
60
+ import javax .servlet .ServletRegistration ;
61
+ import javax .ws .rs .ApplicationPath ;
62
+ import javax .ws .rs .container .ContainerRequestContext ;
63
+ import javax .ws .rs .container .ContainerRequestFilter ;
64
+ import javax .ws .rs .core .UriInfo ;
65
+ import javax .ws .rs .ext .ContextResolver ;
66
+ import java .util .Collections ;
67
+ import java .util .EnumSet ;
68
+ import java .util .List ;
69
+ import java .util .Map .Entry ;
70
+
73
71
/**
74
72
* {@link EnableAutoConfiguration Auto-configuration} for Jersey.
75
73
*
@@ -95,34 +93,20 @@ public class JerseyAutoConfiguration implements ServletContextAware {
95
93
96
94
private final ResourceConfig config ;
97
95
98
- private final List < ResourceConfigCustomizer > customizers ;
96
+ private final JerseyPathResolver pathResolver ;
99
97
100
- private String path ;
98
+ private final List < ResourceConfigCustomizer > customizers ;
101
99
102
100
public JerseyAutoConfiguration (JerseyProperties jersey , ResourceConfig config ,
103
- ObjectProvider <List <ResourceConfigCustomizer >> customizers ) {
101
+ JerseyPathResolver pathResolver , ObjectProvider <List <ResourceConfigCustomizer >> customizers ) {
104
102
this .jersey = jersey ;
105
103
this .config = config ;
104
+ this .pathResolver = pathResolver ;
106
105
this .customizers = customizers .getIfAvailable ();
107
106
}
108
107
109
108
@ PostConstruct
110
- public void path () {
111
- resolveApplicationPath ();
112
- customize ();
113
- }
114
-
115
- private void resolveApplicationPath () {
116
- if (StringUtils .hasLength (this .jersey .getApplicationPath ())) {
117
- this .path = parseApplicationPath (this .jersey .getApplicationPath ());
118
- }
119
- else {
120
- this .path = findApplicationPath (AnnotationUtils .findAnnotation (
121
- this .config .getApplication ().getClass (), ApplicationPath .class ));
122
- }
123
- }
124
-
125
- private void customize () {
109
+ public void customize () {
126
110
if (this .customizers != null ) {
127
111
AnnotationAwareOrderComparator .sort (this .customizers );
128
112
for (ResourceConfigCustomizer customizer : this .customizers ) {
@@ -147,10 +131,10 @@ public FilterRegistrationBean requestContextFilter() {
147
131
public FilterRegistrationBean jerseyFilterRegistration () {
148
132
FilterRegistrationBean registration = new FilterRegistrationBean ();
149
133
registration .setFilter (new ServletContainer (this .config ));
150
- registration .setUrlPatterns (Arrays . asList (this .path ));
134
+ registration .setUrlPatterns (Collections . singletonList (this .pathResolver . getPath () ));
151
135
registration .setOrder (this .jersey .getFilter ().getOrder ());
152
136
registration .addInitParameter (ServletProperties .FILTER_CONTEXT_PATH ,
153
- stripPattern (this .path ));
137
+ stripPattern (this .pathResolver . getPath () ));
154
138
addInitParameters (registration );
155
139
registration .setName ("jerseyFilter" );
156
140
registration .setDispatcherTypes (EnumSet .allOf (DispatcherType .class ));
@@ -169,7 +153,7 @@ private String stripPattern(String path) {
169
153
@ ConditionalOnProperty (prefix = "spring.jersey" , name = "type" , havingValue = "servlet" , matchIfMissing = true )
170
154
public ServletRegistrationBean jerseyServletRegistration () {
171
155
ServletRegistrationBean registration = new ServletRegistrationBean (
172
- new ServletContainer (this .config ), this .path );
156
+ new ServletContainer (this .config ), this .pathResolver . getPath () );
173
157
addInitParameters (registration );
174
158
registration .setName (getServletRegistrationName ());
175
159
registration .setLoadOnStartup (this .jersey .getServlet ().getLoadOnStartup ());
@@ -231,6 +215,77 @@ public void onStartup(ServletContext servletContext) throws ServletException {
231
215
232
216
}
233
217
218
+
219
+ @ Configuration
220
+ static class JerseyPathResolver {
221
+ private final JerseyProperties jersey ;
222
+
223
+ private final ResourceConfig config ;
224
+
225
+ private String path ;
226
+
227
+ JerseyPathResolver (JerseyProperties jersey , ResourceConfig config ) {
228
+ this .jersey = jersey ;
229
+ this .config = config ;
230
+ }
231
+
232
+ public String getPath () {
233
+ return path ;
234
+ }
235
+
236
+ @ PostConstruct
237
+ public void resolveApplicationPath () {
238
+ if (StringUtils .hasLength (this .jersey .getApplicationPath ())) {
239
+ this .path = parseApplicationPath (this .jersey .getApplicationPath ());
240
+ }
241
+ else {
242
+ this .path = findApplicationPath (AnnotationUtils .findAnnotation (
243
+ this .config .getApplication ().getClass (), ApplicationPath .class ));
244
+ }
245
+ }
246
+ }
247
+
248
+ @ Configuration
249
+ // @ConditionalOnBean(CounterService.class) //TODO some Conditional or always for Jersey?
250
+ static class MetricsResourceConfigCustomizer {
251
+ private final String path ;
252
+
253
+ MetricsResourceConfigCustomizer (JerseyPathResolver pathResolver ) {
254
+ String path = pathResolver .getPath ();
255
+ if (path .endsWith ("/*" )){
256
+ path = path .substring (0 , path .lastIndexOf ("/" ));
257
+ }
258
+ this .path = path ;
259
+ }
260
+
261
+ @ Bean
262
+ public ResourceConfigCustomizer resourceConfigCustomizer () {
263
+ return new ResourceConfigCustomizer () {
264
+ @ Override
265
+ public void customize (ResourceConfig config ) {
266
+ config .register (pathTemplateRequestFilter ());
267
+ }
268
+ };
269
+ }
270
+
271
+ @ Bean
272
+ public ContainerRequestFilter pathTemplateRequestFilter () {
273
+ return new ContainerRequestFilter () {
274
+ @ Override
275
+ public void filter (ContainerRequestContext requestContext ) {
276
+ UriInfo uriInfo = requestContext .getUriInfo ();
277
+ if (uriInfo instanceof UriRoutingContext ) {
278
+ List <UriTemplate > templates = ((UriRoutingContext ) uriInfo ).getMatchedTemplates ();
279
+ if (templates .size () == 1 ) {
280
+ //TODO static final somewhere
281
+ requestContext .setProperty ("JERSEY_TEMPLATE" , path + templates .get (0 ).getTemplate ());
282
+ }
283
+ }
284
+ }
285
+ };
286
+ }
287
+ }
288
+
234
289
@ ConditionalOnClass (JacksonFeature .class )
235
290
@ ConditionalOnSingleCandidate (ObjectMapper .class )
236
291
@ Configuration
0 commit comments