You can use a ResourcePatternResolver to get all the resources that match a particular pattern. For example:
Resource[] resources = resourcePatternResolver.getResources("/mydir/*.txt")
You can have a ResourcePatternResolver injected in the same way as ResourceLoader.
You can use a ResourcePatternResolver to get all the resources that match a particular pattern. For example:
Resource[] resources = resourcePatternResolver.getResources("/mydir/*.txt")
You can have a ResourcePatternResolver injected in the same way as ResourceLoader.
Based on Bohemian's comment and another answer, I used the following to get an input streams of all YAMLs under a directory and sub-directories in resources (Note that the path passed doesn't begin with /):
private static Stream<InputStream> getInputStreamsFromClasspath(
String path,
PathMatchingResourcePatternResolver resolver
) {
try {
return Arrays.stream(resolver.getResources("/" + path + "/**/*.yaml"))
.filter(Resource::exists)
.map(resource -> {
try {
return resource.getInputStream();
} catch (IOException e) {
return null;
}
})
.filter(Objects::nonNull);
} catch (IOException e) {
logger.error("Failed to get definitions from directory {}", path, e);
return Stream.of();
}
}
/src/main/resources is a Maven project structure convention. It's a path inside your project where you place resources. During the build step, Maven will take files in there and place them in the appropriate place for you to use them in your runtime classpath, eg in an executable .jar, some physical file system location used in the classpath (with java's -cp option), etc.
I could choose to build my application myself or with a different build tool. In such a case, /src/main/resources would not exist. However, the intention is for the classpath to be the same, ie. to contain the same resources and .class files.
The Spring boot documentation talks about the classpath because it shouldn't make assumptions about how your project is set up.
The classpath also contains additional libraries (JARs), which also can have a static folder, which would then be included for serving static resources. So if the documentation would only state the folder src/main/resources/static, it would be incomplete.
Ad 2: As long as you don't mess with the default Maven configuration, then it's safe to assume this.
Ad 3: Maybe start with the official Oracle documentation: https://docs.oracle.com/javase/8/docs/technotes/tools/windows/classpath.html. Hint: Of course, it's not only the contents of the resources folder, which are in the classpath, but also of course all compiled classes, hence its name.
Videos
In Spring, One solution could be, you can inject the resources array from a folder which is part of classpath
@Value("classpath:path/*")
private Resource[] files;
Assuming your code is built into an executable jar, there’s no src/main/resources in the jar. What you can do is list the contents of the jar file, and then based on the path of each entry, select the ones with csvfiles in the path.
To find out which jar a class is from, see this. To list the contents of a jar file, see this.
Obviously, this won’t work when running locally, so you need an alternative. You can find the location of the class file with this and then navigate to the csvfiles directory relative to it.
The difference is the packaging.
Your IDE does not package your application to run it, it just uses the file system as this is faster.
When you package your app and deploy all the resources that your ide can access from the file system are now packaged within your spring boot fat jar file. In your case the file is inside the my-service-api-2.0.0-SNAPSHOT.jar which is packaged inside your fat jar.
Problem
I need to be able to have a reference to a folder that a user may create in the classpath of my Spring Boot application.
Solution
The following worked for me:
mapperFilesFolder = resolver.getResources("classpath*:" + mappersLocation + "/.");
Path path = Paths.get(mappersFolder[0].getURI());