1 year ago
#70897
tortoiseparrot
How to ensure Spring `Resource::createRelative` returns relative file resource for directory resource without trailing slash?
Hej,
in a Spring Boot application I need to use a base directory on the filesystem and access file resources relative to that.
Spring Boot allows to configure a directory via application.properties
and a file://
URL as value.
When the property is missing its trailing slash, Resource::createRelative()
fails to actually return a relative resource.
What kind of code or configuration do I need to make the createRelative()
call work as intended, e.g. by ensuring that the Resource
ends with a trailing slash?
The follwing test should illustrate my use case / problem:
@SpringBootTest
// NOTE: directory is missing trailing slash
@TestPropertySource(properties = "demo.directory=file://C:/Windows")
class RelativeFileUrlResourceTest {
@ConfigurationProperties(prefix = "demo")
static class TestProperties {
Resource directory;
public Resource getDirectory() {
return directory;
}
public void setDirectory(Resource directory) {
this.directory = directory;
}
}
@TestConfiguration
@EnableConfigurationProperties(TestProperties.class)
static class Config {
}
@Autowired
TestProperties testProperties;
@Test
void givenCreateRelative_thenResourceShouldBeRelative() throws IOException {
Resource directoryResource = testProperties.getDirectory();
File directoryFile = directoryResource.getFile();
assertTrue(directoryFile.isDirectory());
Resource relativeResource = directoryResource.createRelative("relative");
File relativeFile = relativeResource.getFile();
assertEquals(directoryFile, relativeFile.getParentFile());
}
}
The test fails with:
org.opentest4j.AssertionFailedError:
Expected :C:\Windows
Actual :C:\
The magic C:/Windows
value is just an example of a folder that exists and does not have a trailing slash for test purposes. Once the trailing slash is added, i.e. C:/Windows/
, the test passes.
Further note that both the canonical and absolute directory File
do not contain a trailing slash either (at least tested on Windows).
The relative (file) resource is needed to pass it up all the way to a Spring MVC controller while using the Spring Resource
abstraction to access it as a generic InputStream
.
The actual application contains some logic to determine the relative file from the HTTP request instead of a hardcoded "relative" filename.
Is Resource::createRelative()
unfit for this kind of use case? What other abstractions / solutions does Spring (Boot) offer?
java
spring
spring-boot
directory
filepath
0 Answers
Your Answer