Spring框架中的ResourcePatternResolver只能指定jar包内文件,指定容器中文件路径报错:FileNotFoundException

原始代码:

public static  T getFromFile(String specifiedFile, String defaultClasspathFile, Class expectedClass) {
        try {
            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource[] resources = resolver.getResources(defaultClasspathFile);
            Resource resource = resources[0];
            //  获得文件流,因为在jar文件中,不能直接通过文件资源路径拿到文件,但是可以在jar包中拿到文件流
            String json = readFileResource(resource);
            return gson.fromJson(json, expectedClass);
        } catch (Exception e) {
            throw new DtalentInitException(
                    String.format("Fail to init instance of class[%s] by file specifiedFile[%s], defaultFile[%s]",
                            expectedClass, specifiedFile, defaultClasspathFile), e);
        }
    }
private static String readFileResource(Resource resource) throws IOException {
        byte[] bytes = new byte[1024];
        StringBuilder buffer = new StringBuilder("");
        try {
            if(resource.exists()) {
                InputStream stream = resource.getInputStream();
                for (int n; (n = stream.read(bytes)) != -1; ) {
                    buffer.append(new String(bytes, 0, n));
                }
            } else {
            }
            return buffer.toString();
        } catch (IOException e) {
            log.error("Read resource failed.", e);
            throw e;
        }
    }

调用 getFromFile并传入文件路径defaultClasspathFile读取json文件并转为某类的对象

简化代码:

ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource[] resources = resolver.getResources(filePath);
            Resource resource = resources[0];
			log.info("文件是否存在{}",resource.exists())

场景:

只有当上述代码中的filepath是打到jar包内的文件路径时可用,比如resource下的static文件夹,则传入static/xxxx.json;此时可以读到文件并正常解析;

但是当指定一个非jar包内而是jar所在容器内路径如/opt/conf/xxxx.json时,调用方法时就会报错:FileNotFoundException....cannot be opened because it does not exist at org.springframework.core.io.Classload...

原因:

在Spring框架中,Resource是用于访问低级资源的接口,例如文件或类路径资源。ResourcePatternResolver是一个规定了如何解析资源模式的接口。PathMatchingResourcePatternResolver是一个能解析类路径下的文件,以及文件系统中的文件的ResourcePatternResolver实现。

当你在使用ResourcePatternResolvergetResources方法时,你可以指定一个类路径的模式,例如classpath*:com/example/**/*.xml,这将匹配所有名为.xml的文件,这些文件是在com.example包或其任何子包中。

然而,你提到的问题是“如何指定容器中的文件路径”。这个问题的答案取决于你对“容器中的文件路径”的具体含义。

  1. 如果你指的是类路径中的资源,那么你可以使用classpath:classpath*:前缀来指定资源的位置。例如,你可以使用classpath:/templates/mytemplate.txt来获取类路径中的文件。

  2. 如果你指的是文件系统中的资源,那么你可以使用file:前缀来指定资源的位置。例如,你可以使用file:/etc/config/myconfig.txt来获取文件系统中的文件。

  3. 如果你指的是Web应用程序的上下文中的资源,那么你可以使用ServletContextResource来获取这些资源。例如,你可以使用servletContext.getResourceAsStream("/WEB-INF/myfile.txt")来获取/WEB-INF/myfile.txt文件。

需要注意的是,如果你试图访问的资源不存在,那么当你试图打开一个InputStream时,你将会得到一个FileNotFoundException

最后,如果你在容器中的文件路径是动态的,或者你不能确保这些文件在所有环境中都存在,那么你可能需要使用一个更灵活的方法来访问这些资源,例如使用Java的FilePath类,或者使用Spring的ResourceLoader接口。

所以:若想指定容器内的文件路径,则需要增加:file 前缀,如:file:/opt/conf/xxx.json

你可能感兴趣的:(spring,java,后端)