Finally found:
[PathMatching]ResourcePatternResolver
!
Consider:
Testing time:
// ...
import java.util.Arrays;
// import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.support.ResourcePatternResolver; // !!
// ...
@Bean
InitializingBean patternResolverShowCase( /* <- just a demo ... */
/*@Autowired*/ ResourcePatternResolver resolver, /* <- autowire/@value "anywhere"(in spring beans)... */
@Value("${input.file}") String folder, /* <- alternative for @Value: (type-safe) @ConfigurationProperties ;) */
@Value("${input.students.filter}") String studentsFilter, /* < filter1 */
@Value("${input.workers.filter}") String workersFilter /* < filter2 */
) {
return () -> { // <- initializingBean - lambda..
System.err.println( // <- just a demo...
Arrays.toString( // ..do whatever you like with:
resolver.getResources("file:" + folder + "/" + studentsFilter)
)
);
System.err.println(
Arrays.toString( // ... :
resolver.getResources("file:" + folder + "/" + workersFilter)
)
);
};
}
With SpEL
Declaring (assigning name and implementation class, otherwise we get a "nameless default"):
import org.springframework.core.io.support.PathMatchingResourcePatternResolver; // !
// ...
@Bean
ResourcePatternResolver rssResolver() {
return new PathMatchingResourcePatternResolver();
}
..we can also just (SpEL):
import org.springframework.core.io.Resource; // !
// ...
@Value("#{@rssResolver.getResources('file:'+'${input.file}'+'/'+'${input.students.filter}')}") Resource[] studentFiles;
@Value("#{@rssResolver.getResources('file:'+'${input.file}'+'/'+'${input.workers.filter}')}") Resource[] workerFiles;
// do whatever you like with'em (in spring) ...
Explanations
- above link...
- properties, path separator handling and adjustment: to your needs/suits.
@Value("#{...}")
SpEL expression (in a @Value
...).
@rssResolver
refers to "rssResolver" bean.
- plus:
Original answer:
Wildcards will be hard (from @Value
), but this (wiring a
directory into bean context) is easy-peasy:
Properties:
# existing path (win):
myFolder=C:\\temp\\data
# file filter (regex!):
myFileFilter=^test.*\.txt$
Test
@Bean InitializingBean fileResourceShowCase(/* <- just a demo */
@Value("${myFolder}") FileSystemResource rss1, /* <- org.springframework.core.io */
@Value("#{T(java.nio.file.Path).of('${myFolder}')}") Path path, /* <- java.nio */
@Value("#{new java.io.File('${myFolder}')}") File file, /* <- java.io */
@Value("${myFileFilter}") String filter /* <- custom/extra */
) {
return () -> { // 3 ways to access java.io.File:
System.err.println(rss1.getFile());
System.err.println(path.toFile());
System.err.println(file);
// apply the filter:
File[] files = file.listFiles((f) -> f.getName().matches(filter));
for (File f : files) {
System.err.println(f);
}
};
}
Explanations:
@Value("${myFolder}") FileSystemResource rss1
: access the folder as a (spring) FileSystemResource
just by it's name (represented by
${myFolder}
placeholder). [prefer!]
@Value("#{T(java.nio.file.Path).of('${myFolder}')}") Path path
: SpEL expression for (static) Path.of(myFolder)
(where ${myFolder}
is resolved as above).
@Value("#{new java.io.File('${myFolder}')}") File file
: SpEL expression for: new File(myFolder)
...
Links:
Don'ts
Unfortunately we cannot do this with SpEL:
@Value("""
#{
T(java.nio.file.Path).of('${myFolder}')
.toFile()
.listFiles(
(f)->f.getName().matches('${myFileFilter}')
)
}
""") File[] files; // -> EL1042E: Problem parsing right operand ;(;(
see: Why doesn't this stream & lambda expression work with SpEL declaration?
Neither this:
@Value("${myFolder}/**") FileSystemResource[] rssArr // -> java.nio.file.InvalidPathException: Illegal char <*> at index ...
... the last (@Value("${myFolder}/**")
) approach brought me to: https://www.google.com/search?q=spring+antpathmatcher+filesystem ;)