Reputation: 5247
I am trying to get a properties file from within a zip file. I need to use a wild card, because I will want to match either "my.properties" or "my_en.properties". I create a ResourcePatternResolver
like so:
ClassLoader loader = MyClass.class.getClassLoader();
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(loader);
I succeed when I try to retrieve the "my.properties" file using no wild card:
resolver.getResource("file:C:/somePath/a.zip/META-INF/my.properties").exists()
returns true
. However, if I add a wild card to the file name, it fails, e.g.,
resolver.getResource("file:C:/somePath/a.zip/META-INF/my*.properties").exists()
returns false
. What can I do to match and retrieve either file? I am trying to do this in a webapp within Tomcat.
Upvotes: 3
Views: 6084
Reputation: 4532
How suggest Sébastien Helbert getResource and getResources works very different in fact if you see the original Spring Code you can see a this code:
public class PathMatchingResourcePatternResolver implements ResourcePatternResolver {
....
@Override
public Resource getResource(String location) {
return getResourceLoader().getResource(location);
}
@Override
public Resource[] getResources(String locationPattern) throws IOException {
Assert.notNull(locationPattern, "Location pattern must not be null");
if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
// a class path resource (multiple resources for same name possible)
if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
// a class path resource pattern
return findPathMatchingResources(locationPattern);
}
else {
// all class path resources with the given name
return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
}
}
else {
// Generally only look for a pattern after a prefix here,
// and on Tomcat only after the "*/" separator for its "war:" protocol.
int prefixEnd = (locationPattern.startsWith("war:") ? locationPattern.indexOf("*/") + 1 :
locationPattern.indexOf(':') + 1);
if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {
// a file pattern
return findPathMatchingResources(locationPattern);
}
else {
// a single resource with the given name
return new Resource[] {getResourceLoader().getResource(locationPattern)};
}
}
}
...
}
reading the Spring code is clear that getRersources use the AntPattern and geetResource no. I fell it right because with a Wildcards is implicit that you want a multi result and not only one, get resource do not works because it do not take an the common opinion of if I have more that one I take the first, it just do not works because it is no been think in order to works for take the first in case of multi result, it is just a choice. For this reason the your use case, use the wildcard, can be achieved using the getResources() method
I hope that it can help you to take the right method.
Upvotes: 0
Reputation: 2210
The documentation is unclear about this, but the getResource
method does not use PathMatcher internally to resolve the resource (that means that no wildcard is allowed), try getResources(String locationPattern)
instead.
For example :
Resource[] resources = resolver.getResources("file:C:/somePath/a.zip/META-INF/my*.properties");
for(Resource resource : resources) {
// do something for each resource found
}
Upvotes: 3
Reputation: 3045
The official documentation explains it:
No Wildcards:
In the simple case, if the specified location path does not start with the "classpath*:" prefix, and does not contain a PathMatcher pattern, this resolver will simply return a single resource via a getResource() call on the underlying ResourceLoader. Examples are real URLs such as "file:C:/context.xml", pseudo-URLs such as "classpath:/context.xml", and simple unprefixed paths such as "/WEB-INF/context.xml". The latter will resolve in a fashion specific to the underlying ResourceLoader (e.g. ServletContextResource for a WebApplicationContext)
For trying anti-patterns, have a look at:
Upvotes: 0