获取springboot的resources下文件

1 问题描述

以下为PDF导出的部分代码,主要是获取resources下的字体文件。字体文件放置在resources下的/static/fonts目录下,最初设想是先获取字体文件所在目录,再获取目录下文件,主要代码如下:

   /**
     * 构建字体
     */
    private static ConverterProperties buildConvertProperties() throws IOException {
        ConverterProperties converterProperties = new ConverterProperties();
        // 获取字体文件路径
        File fontsDirectory = getClassPathStaticFile(ExportConfig.getFontPath());
        if (!ObjectUtils.isEmpty(fontsDirectory)) {
            // 获取字体文件
            File[] fontFiles = fontsDirectory.listFiles();
            FontProvider fontProvider = new FontProvider();
            if (fontFiles != null && fontFiles.length != 0) {
                for (File file : fontFiles) {
                    FontProgram fontProgram = FontProgramFactory.createFont(file.getAbsolutePath(), true);
                    fontProvider.addFont(fontProgram);
                }
                converterProperties.setFontProvider(fontProvider);
            }
        }
        return converterProperties;
    }

   /**
     * 获取字体文件路径
     */
    public static File getClassPathStaticFile(String classPath) throws FileNotFoundException {
        try {
            ClassPathResource classPathResource = new ClassPathResource(classPath);
            return classPathResource.getFile();
        } catch (Exception e) {
            log.error("获取字体路径错误:" + classPath, e);
            throw new FileNotFoundException("字体获取失败");
        }
    }

在idea中,可以正常获取到字体目录。如果打包后,进行调用,则将会报错FileNotFoundException。这是因为打包后Spring试图访问文件系统路径,但无法访问JAR中的路径。

2023-03-07 17:30:21.602 [http-nio-8085-exec-4] ERROR com.cbex.partyconstruction.common.PdfExportUtil - 获取字体路径错误:/static/fonts
java.io.FileNotFoundException: class path resource [static/fonts] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/E:/zhdjtest/zhdj/boot/zhdj.jar!/static/fonts
        at org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:217) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
        at org.springframework.core.io.AbstractFileResolvingResource.getFile(AbstractFileResolvingResource.java:154) ~[spring-core-5.2.4.RELEASE.jar:5.2.4.RELEASE]
        at com.cbex.partyconstruction.common.PdfExportUtil.getClassPathStaticFile(PdfExportUtil.java:115) [zhdj.jar:?]
        at com.cbex.partyconstruction.common.PdfExportUtil.buildConvertProperties(PdfExportUtil.java:92) [zhdj.jar:?]
        at com.cbex.partyconstruction.common.PdfExportUtil.exportPdfToClient(PdfExportUtil.java:79) [zhdj.jar:?]
        at com.cbex.partyconstruction.common.PdfExportUtil.exportPdfToClient(PdfExportUtil.java:49) [zhdj.jar:?]

2 解决方法

2.1 配置文件全路径

通过文件全路径(绝对路径)读取文件信息。代码修改如下:

   /**
     * 构建字体
     */
    private static ConverterProperties buildConvertProperties() throws IOException {
        ConverterProperties converterProperties = new ConverterProperties();
        // 获取字体文件路径
        File fontsDirectory = getClassPathStaticFile(ExportConfig.getFontPath());
        if (!ObjectUtils.isEmpty(fontsDirectory)) {
            // 获取字体文件
            File[] fontFiles = fontsDirectory.listFiles();
            FontProvider fontProvider = new FontProvider();
            if (fontFiles != null && fontFiles.length != 0) {
                for (File file : fontFiles) {
                    FontProgram fontProgram = FontProgramFactory.createFont(file.getAbsolutePath(), true);
                    fontProvider.addFont(fontProgram);
                }
                converterProperties.setFontProvider(fontProvider);
            }
        }
        return converterProperties;
    }

   /**
     * 获取字体文件路径
     */
    public static File getClassPathStaticFile(String classPath) throws FileNotFoundException {
        try {
            // classPath为磁盘的绝对路径
            return new File(FileUtil.getAbsolutePath(classPath));
        } catch (Exception e) {
            log.error("获取字体路径错误:" + classPath, e);
            throw new FileNotFoundException("字体获取失败");
        }
    }
  • 直接将文件放至目标服务器上,配置文件中字体路径设置为绝对路径
  • 通过maven-assembly-plugin将文件打包到tar包中,但不打进jar包中。配置文件中同样将字体路径设置为绝对路径。相比上一种方式,可以避免部署时遗漏字体文件。
       // 在assembly.xml文件中配置以下信息
       <fileSet>
            <directory>${basedir}/target/classes/static/fonts</directory>
            <outputDirectory>static/fonts</outputDirectory>
            <fileMode>0755</fileMode>
        </fileSet>

2.2 使用文件流

使用文件流的方式进行获取。

  • 优点:字体文件在jar包中,打包后的包可独立运行,不用借助外部文件
  • 缺点:此方法需要配置具体的文件名,如果文件较多,会不太友好
    /**
     * 构建字体
     */
    private static ConverterProperties buildConvertProperties() throws IOException {
        ConverterProperties converterProperties = new ConverterProperties();
        // 获取字体文件名
        List<String> fontName = ExportConfig.getFontName();
        // 获取字体文件所在目录
        String fontPath = ExportConfig.getFontPath();
        FontProvider fontProvider = new FontProvider();
        if (CollUtil.isNotEmpty(fontName)) {
            for (String name : fontName) {
                // 获取文件流
                InputStream stream = PdfExportUtil.class.getClassLoader ().getResourceAsStream(StrUtil.format(FONT_PATH_NAME, fontPath, name));
                assert stream != null;
                final byte[] bytes = IOUtils.toByteArray(stream);
                FontProgram fontProgram = FontProgramFactory.createFont(bytes, true);
                fontProvider.addFont(fontProgram);
            }
            converterProperties.setFontProvider(fontProvider);
        }
        return converterProperties;
    }

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