Skip to content

springresource使用

注意:在jar发布包中,不能使用ResourceUtils.getFile()获取文件,因为它会抛出FileNotFoundException,使用ClassPathResource.getInputStream()方法获取InputStream

示例的详细用法请参考https://gitee.com/dexterleslie/demonstration/tree/master/demo-spring-boot/demo-spring-resource

示例的解析:例子中有demo-third-party-librarydemo-tester两个子项目,demo-third-party-library用于模拟第三方库,demo-tester作为测试用途的项目用于测试引用demo-third-party-library后读取其中的classpath external.properties资源,以达到测试证明ClassPathResource是否有能力读取jar中的classpath资源目的。

运行示例的步骤:

注意:不能从源代码运行此例子。

编译并安装demo-third-party-library到本地maven

bash
cd demo-third-party-library 
mvn package install

编译demo-tester

bash
cd demo-tester
mvn package

运行测试

bash
cd demo-tester
java -jar target/demo.jar

ClassPathResource#exists方法判断classpath资源是否存在

java
ClassPathResource resource = new ClassPathResource("file-none-exists.properties");
Assert.assertFalse(resource.exists());

使用InputStream读取classpath资源

java
// 测试使用InputStream读取classpath资源
// 不抛出异常认为成功读取数据
InputStream inputStream = null;
try {
    resource = new ClassPathResource("file.properties");
    System.out.println("ClassPathResource path: " + resource.getURL().getPath());
    inputStream = resource.getInputStream();
    StreamUtils.copyToByteArray(inputStream);
} finally {
    if(inputStream != null) {
        inputStream.close();
    }
}

在应用发布为jar后,调用ClassPathResource#getFile会报告FileNotFoundException

java
resource = new ClassPathResource("file.properties");
Assert.assertTrue(resource.exists());
try {
    // 调用ClassPathResource.getFile()方法会预期抛出FileNotFoundException
    // 当资源是打包在 JAR、WAR、EAR 或其他归档文件内部时,getFile() 方法将无法直接访问它,因为这些资源并不是以文件系统上的独立文件形式存在的。在这种情况下,尝试调用 getFile() 将会失败,因为文件系统中没有实际的文件与之对应。
    resource.getFile();
    Assert.fail("没有抛出预期异常");
} catch (FileNotFoundException ex) {
    // 预期异常
}

ResourceLoader的使用

java
// 测试ResourceLoader
ClassPathResource classPathResource = new ClassPathResource("file.properties");
ResourceLoader resourceLoader = new DefaultResourceLoader();

// 读取classpath资源
Resource resourceL = resourceLoader.getResource("file.properties");
Assert.assertTrue(resourceL instanceof ClassPathResource);

// 读取classpath资源路径前缀使用classpath:
resourceL = resourceLoader.getResource("classpath:file.properties");
Assert.assertTrue(resourceL instanceof ClassPathResource);

// 使用绝对路径读取classpath资源
// absolutePath例子:file:/home/xxx/workspace-git/demonstration/demo-spring-boot/demo-spring-resource/target/demo.jar!/file.properties
String absolutePath = classPathResource.getURL().getPath();
resourceL = resourceLoader.getResource(absolutePath);
Assert.assertTrue(resourceL instanceof FileUrlResource);

// 读取网络的资源
resourceL = resourceLoader.getResource("https://docs.spring.io/spring/docs/4.0.0.M1/spring-framework-reference/pdf/spring-framework-reference.pdf");
Assert.assertTrue(resourceL instanceof UrlResource);