• 如何在Spring 中将文件作为字符串加载?


    一、概述

    在本文中,将研究将包含文本的资源内容作为 String 注入 Spring beans 的各种方法。

    关注的重点在如何定位资源并读取其内容。

    此外,将演示如何在多个 bean 之间共享加载的资源。通过使用与依赖注入相关的注解来展示这一点,尽管同样可以通过使用基于 XML 的注入并在 XML 属性文件中声明 bean 来实现。

    2. 使用资源

    可以通过使用Resource接口来简化查找资源文件的过程。Spring 帮助我们使用资源加载器查找和读取资源,它根据提供的路径决定选择哪个Resource实现。Resource实际上是一种访问资源内容的方式,而不是内容本身。

    让我们看看获取类路径上资源的Resource实例的一些方法。

    2.1。使用资源加载器

    如果喜欢使用延迟加载,可以使用类ResourceLoader :

    ResourceLoader resourceLoader = new DefaultResourceLoader();
    Resource resource = resourceLoader.getResource("classpath:resource.txt");
    
    • 1
    • 2

    可以使用 @AutowiredResourceLoader注入到 bean 中:**

    @Autowired
    private ResourceLoader resourceLoader;复制
    
    • 1
    • 2

    2.2. 使用 @Value

    可以使用 @ValueResource 直接注入到 Spring bean 中 :

    @Value("classpath:resource.txt")
    private Resource resource;复制
    
    • 1
    • 2

    3. 从资源转换为字符串

    如果需要访问资源,就需要能够将其读入并转化为String。可以使用静态方法asString创建一个ResourceReader实用程序类来为执行此操作。**

    首先,获取一个InputStream

    InputStream inputStream = resource.getInputStream();
    
    • 1

    下一步是获取这个InputStream并将其转换为String。可以使用 Spring 自己的FileCopyUtils#copyToString方法:

    public class ResourceReader {
    
        public static String asString(Resource resource) {
            try (Reader reader = new InputStreamReader(resource.getInputStream(), UTF_8)) {
                return FileCopyUtils.copyToString(reader);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }
    
        // more utility methods
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    还有很多其他方法可以实现这一点,例如,使用Spring 的StreamUtils类的copyToString

    我们还创建另一个实用方法readFileToString, 它将加载对应路径的Resource,并调用asString方法将其转换为String

    public static String readFileToString(String path) {
        ResourceLoader resourceLoader = new DefaultResourceLoader();
        Resource resource = resourceLoader.getResource(path);
        return asString(resource);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.添加 配置类

    如果每个 bean 都必须单独注入资源String,那么有可能会导致 重复代码和每个 bean 拥有自己的String副本而使用更多内存。

    可以通过在加载应用程序上下文时将资源的内容注入一个或多个 Spring bean 来实现更简洁的解决方案。通过这种方式,可以隐藏从需要使用此内容的各种 bean 中读取资源的实现细节。

    @Configuration
    public class LoadResourceConfig {
    
        // Bean Declarations
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    4.1。使用持有资源字符串的 Bean

    声明 bean 以在 @Configuration类中保存资源内容:

    @Bean
    public String resourceString() {
        return ResourceReader.readFileToString("resource.txt");
    }
    
    • 1
    • 2
    • 3
    • 4

    通过@Autowired注释将注册的 bean 注入到字段中:

    public class LoadResourceAsStringIntegrationTest {
        private static final String EXPECTED_RESOURCE_VALUE = "...";  // The string value of the file content
    
        @Autowired
        @Qualifier("resourceString")
        private String resourceString;
    
        @Test
        public void givenUsingResourceStringBean_whenConvertingAResourceToAString_thenCorrect() {
            assertEquals(EXPECTED_RESOURCE_VALUE, resourceString);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这种情况下,使用 @Qualifier注释和 bean 的名称,因为可能需要注入多个相同类型的String字段

    注意,限定符中使用的 bean 名称是从配置类中创建 bean 的方法的名称派生的。

    5. 使用 SpEL

    最后,让我们看看如何使用 Spring 表达式语言来描述将资源文件直接加载到类中的字段中所需的代码。

    使用 @Value注解将文件内容注入到resourceStringUsingSpel字段中:

    public class LoadResourceAsStringIntegrationTest {
        private static final String EXPECTED_RESOURCE_VALUE = "..."; // The string value of the file content
    
        @Value(
          "#{T(com.baeldung.loadresourceasstring.ResourceReader).readFileToString('classpath:resource.txt')}"
        )
        private String resourceStringUsingSpel;
    
        @Test
        public void givenUsingSpel_whenConvertingAResourceToAString_thenCorrect() {
            assertEquals(EXPECTED_RESOURCE_VALUE, resourceStringUsingSpel);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里,调用了ResourceReader#readFileToString,通过使用 “classpath:”来描述文件的位置—— @Value注释中的前缀路径。

    为了减少 SpEL 中的代码量,在ResourceReader类中创建了一个辅助方法, 它使用 Apache Commons FileUtils从提供的路径访问文件:

    public class ResourceReader {
        public static String readFileToString(String path) throws IOException {
            return FileUtils.readFileToString(ResourceUtils.getFile(path), StandardCharsets.UTF_8);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    六,总结

    在本文中,回顾了一些将资源转换为String的方法。

    首先,看了如何生成一个Resource来访问文件,以及如何从Resource读取到String。

    接下来,展示了如何隐藏资源加载实现,并通过在 @Configuration中创建合格的 bean 来允许字符串内容在 bean 之间共享,从而允许字符串自动装配。

    最后,使用了 SpEL,它提供了一个紧凑而直接的解决方案,尽管它需要一个自定义帮助函数来阻止它变得过于复杂。

    与往常一样,示例代码可以在 GitHub 上找到

    原文

  • 相关阅读:
    Leetcode 1239. 串联字符串的最大长度
    淘宝服务端高并发分布式架构演进之路
    linux 下的帮助接口argp_parse()实战
    Py使用requests爬虫1(基础+入门)
    nginx负载均衡配置详解
    【LeetCode】最长连续序列 [M](数据结构设计)
    『亚马逊云科技产品测评』活动征文|搭建图床chevereto
    【MySQL】1.索引
    门店管理|火锅店数字化系统转型
    Java.lang.Class类 isSynthetic()方法有什么功能呢?
  • 原文地址:https://blog.csdn.net/xuejianxinokok/article/details/127744275