Skip to content

Commit 436486b

Browse files
committed
Relax ServletContext check for resource handling
This is a follow-up on commit 3b95e0b relaxing the expectation that a ServletContext is present. Instead we check defensively and fall back on PathExtensionContentNegotiationStrategy which can use JAF. Issue: SPR-14577
1 parent e7aecb4 commit 436486b

File tree

3 files changed

+20
-13
lines changed

3 files changed

+20
-13
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import java.util.HashMap;
2323
import java.util.List;
2424
import java.util.Map;
25-
import javax.servlet.ServletContext;
2625
import javax.servlet.ServletException;
2726
import javax.servlet.ServletResponse;
2827
import javax.servlet.http.HttpServletRequest;
@@ -32,6 +31,7 @@
3231
import org.apache.commons.logging.LogFactory;
3332

3433
import org.springframework.beans.factory.InitializingBean;
34+
import org.springframework.beans.factory.SmartInitializingSingleton;
3535
import org.springframework.core.io.Resource;
3636
import org.springframework.core.io.support.ResourceRegion;
3737
import org.springframework.http.HttpHeaders;
@@ -91,7 +91,7 @@
9191
* @since 3.0.4
9292
*/
9393
public class ResourceHttpRequestHandler extends WebContentGenerator
94-
implements HttpRequestHandler, InitializingBean, CorsConfigurationSource {
94+
implements HttpRequestHandler, InitializingBean, SmartInitializingSingleton, CorsConfigurationSource {
9595

9696
// Servlet 3.1 setContentLengthLong(long) available?
9797
private static final boolean contentLengthLongAvailable =
@@ -112,9 +112,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
112112

113113
private ContentNegotiationManager contentNegotiationManager;
114114

115-
private ServletPathExtensionContentNegotiationStrategy pathExtensionStrategy;
116-
117-
private ServletContext servletContext;
115+
private PathExtensionContentNegotiationStrategy pathExtensionStrategy;
118116

119117
private CorsConfiguration corsConfiguration;
120118

@@ -248,11 +246,6 @@ public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
248246
return this.corsConfiguration;
249247
}
250248

251-
@Override
252-
protected void initServletContext(ServletContext servletContext) {
253-
this.servletContext = servletContext;
254-
}
255-
256249

257250
@Override
258251
public void afterPropertiesSet() throws Exception {
@@ -270,7 +263,6 @@ public void afterPropertiesSet() throws Exception {
270263
if (this.resourceRegionHttpMessageConverter == null) {
271264
this.resourceRegionHttpMessageConverter = new ResourceRegionHttpMessageConverter();
272265
}
273-
this.pathExtensionStrategy = initPathExtensionStrategy();
274266
}
275267

276268
/**
@@ -293,7 +285,12 @@ protected void initAllowedLocations() {
293285
}
294286
}
295287

296-
protected ServletPathExtensionContentNegotiationStrategy initPathExtensionStrategy() {
288+
@Override
289+
public void afterSingletonsInstantiated() {
290+
this.pathExtensionStrategy = initContentNegotiationStrategy();
291+
}
292+
293+
protected PathExtensionContentNegotiationStrategy initContentNegotiationStrategy() {
297294
Map<String, MediaType> mediaTypes = null;
298295
if (getContentNegotiationManager() != null) {
299296
PathExtensionContentNegotiationStrategy strategy =
@@ -302,7 +299,9 @@ protected ServletPathExtensionContentNegotiationStrategy initPathExtensionStrate
302299
mediaTypes = new HashMap<>(strategy.getMediaTypes());
303300
}
304301
}
305-
return new ServletPathExtensionContentNegotiationStrategy(this.servletContext, mediaTypes);
302+
return (getServletContext() != null) ?
303+
new ServletPathExtensionContentNegotiationStrategy(getServletContext(), mediaTypes) :
304+
new PathExtensionContentNegotiationStrategy(mediaTypes);
306305
}
307306

308307

spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistryTests.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ public void mapPathToLocation() throws Exception {
7979
request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/testStylesheet.css");
8080

8181
ResourceHttpRequestHandler handler = getHandler("/resources/**");
82+
handler.afterPropertiesSet();
83+
handler.afterSingletonsInstantiated();
8284
handler.handleRequest(request, this.response);
8385

8486
assertEquals("test stylesheet content", this.response.getContentAsString());

spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ public void setUp() throws Exception {
8181
this.handler.setCacheSeconds(3600);
8282
this.handler.setServletContext(new TestServletContext());
8383
this.handler.afterPropertiesSet();
84+
this.handler.afterSingletonsInstantiated();
8485

8586
this.request = new MockHttpServletRequest("GET", "");
8687
this.response = new MockHttpServletResponse();
@@ -147,6 +148,7 @@ public void getVersionedResource() throws Exception {
147148
.addFixedVersionStrategy("versionString", "/**");
148149
this.handler.setResourceResolvers(Arrays.asList(versionResolver, new PathResourceResolver()));
149150
this.handler.afterPropertiesSet();
151+
this.handler.afterSingletonsInstantiated();
150152

151153
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "versionString/foo.css");
152154
this.handler.handleRequest(this.request, this.response);
@@ -253,6 +255,7 @@ public void getResourceWithRegisteredMediaType() throws Exception {
253255
handler.setLocations(paths);
254256
handler.setContentNegotiationManager(manager);
255257
handler.afterPropertiesSet();
258+
handler.afterSingletonsInstantiated();
256259

257260
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
258261
handler.handleRequest(this.request, this.response);
@@ -274,6 +277,7 @@ public void getMediaTypeWithFavorPathExtensionOff() throws Exception {
274277
handler.setLocations(paths);
275278
handler.setContentNegotiationManager(manager);
276279
handler.afterPropertiesSet();
280+
handler.afterSingletonsInstantiated();
277281

278282
this.request.addHeader("Accept", "application/json,text/plain,*/*");
279283
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.html");
@@ -302,6 +306,7 @@ public String getVirtualServerName() {
302306
handler.setServletContext(servletContext);
303307
handler.setLocations(paths);
304308
handler.afterPropertiesSet();
309+
handler.afterSingletonsInstantiated();
305310

306311
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
307312
handler.handleRequest(this.request, this.response);
@@ -416,6 +421,7 @@ public void initAllowedLocationsWithExplicitConfiguration() throws Exception {
416421
handler.setServletContext(new MockServletContext());
417422
handler.setLocations(Arrays.asList(location1, location2));
418423
handler.afterPropertiesSet();
424+
handler.afterSingletonsInstantiated();
419425

420426
Resource[] locations = pathResolver.getAllowedLocations();
421427
assertEquals(1, locations.length);

0 commit comments

Comments
 (0)