Why doesn't Spring's PathMatchingResourcePatternResolver match “*” with nothing?

只愿长相守 提交于 2021-02-09 07:05:15

问题


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.


回答1:


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
}



回答2:


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:

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/io/support/PathMatchingResourcePatternResolver.html




回答3:


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.



来源:https://stackoverflow.com/questions/51085357/why-doesnt-springs-pathmatchingresourcepatternresolver-match-with-nothing

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!