Respect Boot locations in MockServletContext
Update SpringApplicationContextLoader to use a MockServletContext subclass which also respects common Spring Boot resource locations. This allows resources in `/META-INF/resources`, `/resources`, `/public` and `/static` to be loaded in the same way as those in `/src/main/webapp`. SpringBootMockServletContext also returns an empty temporary folder for '/' when no resource locations can be found. This is primarily to prevent superfluous warnings from Liquibase. Fixes gh-2654pull/2615/merge
parent
7d3465f858
commit
0a33d0464d
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.springframework.core.io.FileSystemResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
|
||||
/**
|
||||
* {@link MockServletContext} implementation for Spring Boot. Respects well know Spring
|
||||
* Boot resource locations and uses an empty folder for "/" if no locations can be found.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class SpringBootMockServletContext extends MockServletContext {
|
||||
|
||||
private static final String[] SPRING_BOOT_RESOURCE_LOCATIONS = new String[] {
|
||||
"classpath:META-INF/resources", "classpath:resources", "classpath:static",
|
||||
"classpath:public" };
|
||||
|
||||
private final ResourceLoader resourceLoader;
|
||||
|
||||
private File emptyRootFolder;
|
||||
|
||||
public SpringBootMockServletContext(String resourceBasePath) {
|
||||
this(resourceBasePath, new FileSystemResourceLoader());
|
||||
}
|
||||
|
||||
public SpringBootMockServletContext(String resourceBasePath,
|
||||
ResourceLoader resourceLoader) {
|
||||
super(resourceBasePath, resourceLoader);
|
||||
this.resourceLoader = resourceLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getResourceLocation(String path) {
|
||||
if (!path.startsWith("/")) {
|
||||
path = "/" + path;
|
||||
}
|
||||
String resourceLocation = getResourceBasePathLocation(path);
|
||||
if (exists(resourceLocation)) {
|
||||
return resourceLocation;
|
||||
}
|
||||
for (String prefix : SPRING_BOOT_RESOURCE_LOCATIONS) {
|
||||
resourceLocation = prefix + path;
|
||||
if (exists(resourceLocation)) {
|
||||
return resourceLocation;
|
||||
}
|
||||
}
|
||||
return super.getResourceLocation(path);
|
||||
}
|
||||
|
||||
protected final String getResourceBasePathLocation(String path) {
|
||||
return super.getResourceLocation(path);
|
||||
}
|
||||
|
||||
private boolean exists(String resourceLocation) {
|
||||
try {
|
||||
Resource resource = this.resourceLoader.getResource(resourceLocation);
|
||||
return resource.exists();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getResource(String path) throws MalformedURLException {
|
||||
URL resource = super.getResource(path);
|
||||
if (resource == null && "/".equals(path)) {
|
||||
// Liquibase assumes that "/" always exists, if we don't have a folder
|
||||
// use a temporary location.
|
||||
try {
|
||||
if (this.emptyRootFolder == null) {
|
||||
synchronized (this) {
|
||||
File tempFolder = File.createTempFile("spr", "servlet");
|
||||
tempFolder.delete();
|
||||
tempFolder.mkdirs();
|
||||
tempFolder.deleteOnExit();
|
||||
this.emptyRootFolder = tempFolder;
|
||||
}
|
||||
}
|
||||
return this.emptyRootFolder.toURI().toURL();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
}
|
||||
}
|
||||
return resource;
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
import org.springframework.web.context.ServletContextAware;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link SpringBootMockServletContext}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = SpringBootMockServletContextTests.Config.class)
|
||||
@WebAppConfiguration("src/test/webapp")
|
||||
public class SpringBootMockServletContextTests implements ServletContextAware {
|
||||
|
||||
private ServletContext servletContext;
|
||||
|
||||
@Override
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
this.servletContext = servletContext;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getResourceLocation() throws Exception {
|
||||
testResource("/inwebapp", "src/test/webapp");
|
||||
testResource("/inmetainfresources", "/META-INF/resources");
|
||||
testResource("/inresources", "/resources");
|
||||
testResource("/instatic", "/static");
|
||||
testResource("/inpublic", "/public");
|
||||
}
|
||||
|
||||
private void testResource(String path, String expectedLocation)
|
||||
throws MalformedURLException {
|
||||
URL resource = this.servletContext.getResource(path);
|
||||
assertThat("Path " + path + " not found", resource, not(nullValue()));
|
||||
assertThat("Path " + path + " not in " + expectedLocation, resource.getPath(),
|
||||
containsString(expectedLocation));
|
||||
}
|
||||
|
||||
// gh-2654
|
||||
@Test
|
||||
public void getRootUrlExistsAndIsEmpty() throws Exception {
|
||||
SpringBootMockServletContext context = new SpringBootMockServletContext(
|
||||
"src/test/doesntexist") {
|
||||
@Override
|
||||
protected String getResourceLocation(String path) {
|
||||
// Don't include the Spring Boot defaults for this test
|
||||
return getResourceBasePathLocation(path);
|
||||
};
|
||||
};
|
||||
URL resource = context.getResource("/");
|
||||
assertThat(resource, not(nullValue()));
|
||||
File file = new File(resource.getPath());
|
||||
String[] contents = file.list(new FilenameFilter() {
|
||||
@Override
|
||||
public boolean accept(File dir, String name) {
|
||||
return !(".".equals(name) || "..".equals(name));
|
||||
}
|
||||
});
|
||||
assertThat(contents, not(nullValue()));
|
||||
assertThat(contents.length, equalTo(0));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class Config {
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue