From 1eaaa9a446c664991f9cb744e9dbcde8b6bca357 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 1 May 2012 17:08:19 -0400 Subject: [PATCH] Add empty location check to ResourceHttpRequestHandler ResourceHttpRequestHandler now implements InitializingBean and checks for empty locations. Issue: SPR-9186 --- .../resource/ResourceHttpRequestHandler.java | 10 +++-- .../ResourceHttpRequestHandlerTests.java | 37 +++++++++++-------- 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java index a66aaf0cdea..a4cc6669a5a 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java @@ -25,6 +25,7 @@ import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.InitializingBean; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.http.MediaType; @@ -38,7 +39,7 @@ import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.support.WebContentGenerator; /** - * {@link HttpRequestHandler} that serves static resources optimized for superior browser performance + * {@link HttpRequestHandler} that serves static resources optimized for superior browser performance * (according to the guidelines of Page Speed, YSlow, etc.) by allowing for flexible cache settings * ({@linkplain #setCacheSeconds "cacheSeconds" property}, last-modified support). * @@ -50,7 +51,7 @@ import org.springframework.web.servlet.support.WebContentGenerator; * (if present) so that a {@code 304} status code will be returned as appropriate, avoiding unnecessary * overhead for resources that are already cached by the client. The use of {@code Resource} locations * allows resource requests to easily be mapped to locations other than the web application root. For - * example, resources could be served from a classpath location such as "classpath:/META-INF/public-web-resources/", + * example, resources could be served from a classpath location such as "classpath:/META-INF/public-web-resources/", * allowing convenient packaging and serving of resources such as a JavaScript library from within jar files. * *

To ensure that users with a primed browser cache get the latest changes to application-specific @@ -66,7 +67,7 @@ import org.springframework.web.servlet.support.WebContentGenerator; * @author Juergen Hoeller * @since 3.0.4 */ -public class ResourceHttpRequestHandler extends WebContentGenerator implements HttpRequestHandler { +public class ResourceHttpRequestHandler extends WebContentGenerator implements HttpRequestHandler, InitializingBean { private static final boolean jafPresent = ClassUtils.isPresent("javax.activation.FileTypeMap", ResourceHttpRequestHandler.class.getClassLoader()); @@ -87,6 +88,9 @@ public class ResourceHttpRequestHandler extends WebContentGenerator implements H this.locations = locations; } + public void afterPropertiesSet() throws Exception { + Assert.notEmpty(locations, "Locations list must not be empty"); + } /** * Processes a resource request. diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java index cf2761718fb..6593ccdf053 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java @@ -41,7 +41,7 @@ import static org.junit.Assert.*; public class ResourceHttpRequestHandlerTests { private ResourceHttpRequestHandler handler; - + @Before public void setUp() { List resourcePaths = new ArrayList(); @@ -52,7 +52,7 @@ public class ResourceHttpRequestHandlerTests { handler.setCacheSeconds(3600); handler.setServletContext(new TestServletContext()); } - + @Test public void getResource() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); @@ -65,11 +65,11 @@ public class ResourceHttpRequestHandlerTests { assertTrue(Long.valueOf(response.getHeader("Expires")) >= System.currentTimeMillis() - 1000 + (3600 * 1000)); assertEquals("max-age=3600, must-revalidate", response.getHeader("Cache-Control")); assertTrue(response.containsHeader("Last-Modified")); - assertEquals(Long.valueOf(response.getHeader("Last-Modified")).longValue(), + assertEquals(Long.valueOf(response.getHeader("Last-Modified")).longValue(), new ClassPathResource("test/foo.css", getClass()).getFile().lastModified()); assertEquals("h1 { color:red; }", response.getContentAsString()); } - + @Test public void getResourceWithHtmlMediaType() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); @@ -81,10 +81,10 @@ public class ResourceHttpRequestHandlerTests { assertTrue(Long.valueOf(response.getHeader("Expires")) >= System.currentTimeMillis() - 1000 + (3600 * 1000)); assertEquals("max-age=3600, must-revalidate", response.getHeader("Cache-Control")); assertTrue(response.containsHeader("Last-Modified")); - assertEquals(Long.valueOf(response.getHeader("Last-Modified")).longValue(), + assertEquals(Long.valueOf(response.getHeader("Last-Modified")).longValue(), new ClassPathResource("test/foo.html", getClass()).getFile().lastModified()); } - + @Test public void getResourceFromAlternatePath() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); @@ -97,11 +97,11 @@ public class ResourceHttpRequestHandlerTests { assertTrue(Long.valueOf(response.getHeader("Expires")) >= System.currentTimeMillis() - 1000 + (3600 * 1000)); assertEquals("max-age=3600, must-revalidate", response.getHeader("Cache-Control")); assertTrue(response.containsHeader("Last-Modified")); - assertEquals(Long.valueOf(response.getHeader("Last-Modified")).longValue(), + assertEquals(Long.valueOf(response.getHeader("Last-Modified")).longValue(), new ClassPathResource("testalternatepath/baz.css", getClass()).getFile().lastModified()); assertEquals("h1 { color:red; }", response.getContentAsString()); } - + @Test public void getResourceFromSubDirectory() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); @@ -112,7 +112,7 @@ public class ResourceHttpRequestHandlerTests { assertEquals("text/javascript", response.getContentType()); assertEquals("function foo() { console.log(\"hello world\"); }", response.getContentAsString()); } - + @Test public void getResourceFromSubDirectoryOfAlternatePath() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); @@ -138,7 +138,7 @@ public class ResourceHttpRequestHandlerTests { response = new MockHttpServletResponse(); handler.handleRequest(request, response); assertEquals(404, response.getStatus()); - + handler.setLocations(Arrays.asList(new ClassPathResource("testsecret/", getClass()))); request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "secret.txt"); response = new MockHttpServletResponse(); @@ -158,7 +158,7 @@ public class ResourceHttpRequestHandlerTests { handler.handleRequest(request, response); assertEquals(HttpServletResponse.SC_NOT_MODIFIED, response.getStatus()); } - + @Test public void modified() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); @@ -169,9 +169,9 @@ public class ResourceHttpRequestHandlerTests { MockHttpServletResponse response = new MockHttpServletResponse(); handler.handleRequest(request, response); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); - assertEquals("h1 { color:red; }", response.getContentAsString()); + assertEquals("h1 { color:red; }", response.getContentAsString()); } - + @Test public void directory() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); @@ -191,7 +191,7 @@ public class ResourceHttpRequestHandlerTests { handler.handleRequest(request, response); assertEquals(404, response.getStatus()); } - + @Test(expected=IllegalStateException.class) public void noPathWithinHandlerMappingAttribute() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); @@ -199,7 +199,7 @@ public class ResourceHttpRequestHandlerTests { MockHttpServletResponse response = new MockHttpServletResponse(); handler.handleRequest(request, response); } - + @Test(expected=HttpRequestMethodNotSupportedException.class) public void unsupportedHttpMethod() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); @@ -208,7 +208,7 @@ public class ResourceHttpRequestHandlerTests { MockHttpServletResponse response = new MockHttpServletResponse(); handler.handleRequest(request, response); } - + @Test public void resourceNotFound() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest(); @@ -219,6 +219,11 @@ public class ResourceHttpRequestHandlerTests { assertEquals(404, response.getStatus()); } + @Test(expected=IllegalArgumentException.class) + public void locationsNotSet() throws Exception { + new ResourceHttpRequestHandler().afterPropertiesSet(); + } + private static class TestServletContext extends MockServletContext {