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

  • Post author:
  • Post category:其他




一、概述

在本文中,将研究

将包含文本的资源内容作为 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");

可以使用

@Autowired



ResourceLoader

注入到 bean 中:**

@Autowired
private ResourceLoader resourceLoader;复制



2.2. 使用

@Value

可以使用

@Value



Resource

直接注入到 Spring bean 中 :

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



3. 从

资源

转换为

字符串

如果需要访问

资源

,就需要能够将其读入并转化为

String

。可以使用静态方法

asString

创建一个

ResourceReader

实用程序类来为执行此操作。**

首先,获取一个

InputStream

InputStream inputStream = resource.getInputStream();

下一步是获取这个

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
}

还有

很多其他方法可以实现这一点

,例如,使用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);
}



4.添加 配置类

如果每个 bean 都必须单独注入资源

String

,那么有可能会导致 重复代码和每个 bean 拥有自己的

String

副本而使用更多内存。

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

@Configuration
public class LoadResourceConfig {

    // Bean Declarations
}



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

声明 bean 以在

@Configuration

类中保存资源内容:

@Bean
public String resourceString() {
    return ResourceReader.readFileToString("resource.txt");
}

通过


@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);
    }
}

在这种情况下,使用

@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);
    }
}

在这里,调用了

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);
    }
}



六,总结

在本文中,回顾了一些

将资源转换为

String


的方法。

首先,看了如何生成一个

Resource

来访问文件,以及如何从

Resource

读取到

String。

接下来,展示了如何隐藏资源加载实现,并通过在

@Configuration

中创建合格的 bean 来允许字符串内容在 bean 之间共享,从而允许字符串自动装配。

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

与往常一样,示例代码可以

在 GitHub 上找到


原文



版权声明:本文为xuejianxinokok原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。