背景
項目開發過程中我們我們會遇到訪問靜態文件的情況,例如word書簽模板,excel導入模板,條文法規文件等,在war包的情況下訪問是沒有問題的,如果使用jar包部署,使用相對路徑訪問會出現問題,本文就此問題給出解決方案。
配置
resources文件夾下創建靜態目錄systemfile,放入測試文件test.docx(文件名需要命名為英文)
pom文件resource/build節點設置打包編譯忽略systemfile文件夾
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<excludes>
<exclude>systemfile/*</exclude>
</excludes>
</resource>
<resource>
<filtering>false</filtering>
<directory>src/main/resources</directory>
<includes>
<include>systemfile/*</include>
</includes>
</resource>
</resources>
訪問
使用ClassPathResource的getInputStream獲取jar包中的文件的流暫存到磁盤的臨時文件中,直接訪問臨時文件即可
String testFilePath = ClassPathFileUtil.getFilePath("systemfile/test.docx");
public static String getFilePath(String classFilePath) {
String filePath = "";
try {
String templateFilePath = "tempfiles/classpathfile/";
File tempDir = new File(templateFilePath);
if (!tempDir.exists()) {
tempDir.mkdirs();
}
String[] filePathList = classFilePath.split("/");
String checkFilePath = "tempfiles/classpathfile";
for (String item : filePathList) {
checkFilePath += "/" + item;
}
File tempFile = new File(checkFilePath);
if (tempFile.exists()) {
filePath = checkFilePath;
} else {
//解析
ClassPathResource classPathResource = new ClassPathResource(classFilePath);
InputStream inputStream = classPathResource.getInputStream();
checkFilePath = "tempfiles/classpathfile";
for (int i = 0; i < filePathList.length; i++) {
checkFilePath += "/" + filePathList[i];
if (i==filePathList.length-1) {
//文件
File file = new File(checkFilePath);
FileUtils.copyInputStreamToFile(inputStream, file);
}else{
//目錄
tempDir = new File(checkFilePath);
if (!tempDir.exists()) {
tempDir.mkdirs();
}
}
}
inputStream.close();
filePath = checkFilePath;
}
} catch (Exception e) {
e.printStackTrace();
}
return filePath;
}
注意
項目啟動時,需要清除靜態文件的臨時文件,避免文件更新
@Component
@Order(value = 10)
public class StartUpContext implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
String templateFilePath = "tempfiles/classpathfile/";
File tempDir = new File(templateFilePath);
FileSystemUtils.deleteRecursively(tempDir);
System.out.println("清除classpathfile臨時文件成功");
}