アサシンの多重問題現象:
今日、プロジェクト内でビジネス シナリオが発生し、リソースリソース ディレクトリ内のファイルを使用する必要がありました。そのとき、次のような質問について考えていました。
プロジェクトが jar にパッケージ化されている場合、Springboot はどのようにしてリソース リソース ディレクトリ内のファイルを取得しますか?
問題分析:
タイトルのように、プロジェクトを jar パッケージにパッケージ化した後でも、コード内で jar パッケージのリソース ディレクトリ内のファイルを取得するにはどうすればよいですか?
リソース リソース ディレクトリにあるファイルを取得するには多くの方法があることは誰もが知っています。これらの方法は、通常のデバッグでプロジェクトをローカルで実行する場合には効果的ですが、プロジェクトがパッケージ化され、jar として実行される場合には、そのすべてが効果的であるわけではありません。パッケージです!!!
したがって、ここではプロテストと実行可能な方法を記録するつもりです。
まず、プロジェクトの構造を示します。図に示すように、resources リソース ディレクトリの下にフォルダー ルールを作成し、その中に 3 つの drl ファイルを作成しました。
コード ロジックは非常に単純なので、ここでクラスを開始することで直接テストされます。
リソースデモアプリケーション:
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import java.io.File;
import java.io.IOException;
/**
* resource资源目录专题
* @author Stephen
*/
@SpringBootApplication
public class ResourceDemoApplication {
public static void main(String[] args) {
// SpringApplication.run(ResourceDemoApplication.class, args);
try {
//如何获取resource下的文件?【注意:即使打成jar包也得有效】
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resourcePatternResolver.getResources("classpath*:rules/**/*.*");
for ( Resource resource : resources ) {
//获取文件名
System.out.println(resource.getFilename());
//获取文件,该方式在打成jar包后会报错,因为resource文件不在系统中,而是在jar包中
File file1 = resource.getFile();
//获取文件,在打成jar包后,通过url来获取文件,则路径是正确的
File file = new File(resource.getURL().getFile());
//获取文件绝对路径,但路径有问题,因为resource文件不在系统中,而是在jar包中
// System.out.println(file.getAbsolutePath());
//获取文件名
System.out.println(file.getName());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
以下に実行結果を示します。
まずローカルプロジェクト:
ご覧のとおり、ファイル名が非常にスムーズに出力されます。
次に、jar パッケージが実行されます。
こちらも問題ありません。
知らせ:
ResourceDemoApplicationスタートアップ クラスには、コメント アウトされたコード行が 2 行あること に注意してください 。
上記のコード行はローカルで実行するのには問題ありませんが、jar パッケージとして実行すると次のエラーが表示されるため、使用はお勧めできません。
表示されるファイルパスは次のとおりです。
jar:file:/C:/Users/Administrator/Desktop/resource_demo-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/rules/comparison-rules.drl
resource_demo-0.0.1-SNAPSHOT.jarの後に!が付いて いることがわかります。これは、対応する drl ファイルのターゲット パッケージ内のパスです。詳細は調べていませんが、この暴力的な部分だけを分析すると、 file path, my このファイル パスは実際には偽のパスであり、ファイルの実際の URL アドレスではないため、リソース オブジェクトを通じてファイルを取得できないことが理解されています。
コメント化されたコードの別の行は次のとおりです。
このコード行を実行すると、jar パッケージが実行中であってもエラーは報告されませんが、jar パッケージが実行中である場合、出力されるファイルの絶対パスは実際のパスではありません。つまり、システムはそれを認識できません。このファイルは jar パッケージ内にあるため、パスは次のようになります。
拡張子がある場合は、後で追加されます。
解決:
try {
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
Resource[] resources = resourcePatternResolver.getResources("classpath*:rules/**/*.*");
for ( Resource resource : resources ) {
//获取文件,在打成jar包后,通过url来获取文件,则路径是正确的
File file = new File(resource.getURL().getFile());
}
} catch (IOException e) {
e.printStackTrace();
}