Acesse um arquivo do caminho de classe em um aplicativo Spring

Acesse um arquivo do caminho de classe em um aplicativo Spring

1. Introdução

Neste tutorial, veremos várias maneiras de acessar e carregar o conteúdo de um arquivo que está no classpath usando Spring.

Leitura adicional:

Um guia para o ResourceBundle

É sempre um desafio manter e estender aplicativos multilíngues. Este artigo aborda como usar o ResourceBundle para lidar com as variedades que surgem quando você precisa fornecer o mesmo conteúdo para diferentes culturas.

Read more

Carregar um recurso como uma string no Spring

Aprenda como injetar o conteúdo de um arquivo de recurso em nossos beans como uma String, com a classe Resource do Spring tornando isso muito fácil.

Read more

2. UsandoResource

A sinterfaceResource ajuda a abstrair o acesso a recursos de baixo nível. De fato, ele suporta o manuseio de todos os tipos de recursos de arquivo de maneira uniforme.

Vamos começar examinando vários métodos para obter uma instânciaResource.

2.1. Manualmente

Para acessar um recurso do classpath, podemos simplesmente usarClassPathResource:

public Resource loadEmployees() {
    return new ClassPathResource("data/employees.dat");
}

Por padrão,ClassPathResource remove alguns clichês para selecionar entre o carregador de classe de contexto do thread e o carregador de classe do sistema padrão

No entanto, também podemos indicar o carregador de classes a ser usado diretamente:

return new ClassPathResource("data/employees.dat", this.getClass().getClassLoader());

Ou indiretamente através de uma classe especificada:

return new ClassPathResource(
  "data/employees.dat",
  Employee.class.getClassLoader());

Observe que deResource, podemos facilmente pular para representações padrão Java comoInputStream orFile.

Outra coisa a notar aqui é que o método acima funciona apenas para caminhos absolutos. Se você quiser especificar um caminho relativo, você pode passar um segundo argumentoclass. O caminho será relativo a esta classe:

new ClassPathResource("../../../data/employees.dat", Example.class).getFile();

O caminho do arquivo acima é relativo à classeExample.

2.2. Usando@Value

Também podemos injetar umResource com@Value:

@Value("classpath:data/resource-data.txt")
Resource resourceFile;

E@Value também suporta outros prefixos, comofile:eurl:.

2.3. Usando ResourceLoader

Ou, se quisermos carregar lentamente nosso recurso, podemos usarResourceLoader:

@Autowired
ResourceLoader resourceLoader;

E então recuperamos nosso recurso comgetResource:

public Resource loadEmployees() {
    return resourceLoader.getResource(
      "classpath:data/employees.dat");
}

Observe também queResourceLoader é implementado por todos osApplicationContexts concretos, o que significa que também podemos simplesmente depender deApplicationContext if que se adapte melhor à nossa situação:

ApplicationContext context;

public Resource loadEmployees() {
    return context.getResource("classpath:data/employees.dat");
}

3. UsandoResourceUtils

Como advertência, há outra maneira de recuperar recursos no Spring, masResourceUtils Javadoc deixa claro que a classe é principalmente para uso interno.

Se virmos usos deResourceUtils em nosso código:

public File loadEmployeesWithSpringInternalClass()
  throws FileNotFoundException {
    return ResourceUtils.getFile(
      "classpath:data/employees.dat");
}

Devemos considerar cuidadosamente a justificativa comoit’s probably better to use one of the standard approaches above.

4. Leitura de dados de recursos

Assim que tivermos umResource, , será fácil ler o conteúdo. Como já discutimos, podemos facilmente obter uma referênciaFile ouInputStream a partir deResource.

Vamos imaginar que temos o seguinte arquivo,data/employees.dat, no classpath:

Joe Employee,Jan Employee,James T. Employee

4.1. Lendo como umFile

Agora, podemos ler seu conteúdo chamandogetFile:

@Test
public void whenResourceAsFile_thenReadSuccessful()
  throws IOException {

    File resource = new ClassPathResource(
      "data/employees.dat").getFile();
    String employees = new String(
      Files.readAllBytes(resource.toPath()));
    assertEquals(
      "Joe Employee,Jan Employee,James T. Employee",
      employees);
}

Embora, observe que esta abordagemexpects the resource to be present in the filesystem and not within a jar file.

4.2. Lendo como umInputStream

Digamos, porém, que nosso recursois dentro de um jar.

Então, podemos ler umResource como umInputStream:

@Test
public void whenResourceAsStream_thenReadSuccessful()
  throws IOException {
    InputStream resource = new ClassPathResource(
      "data/employees.dat").getInputStream();
    try ( BufferedReader reader = new BufferedReader(
      new InputStreamReader(resource)) ) {
        String employees = reader.lines()
          .collect(Collectors.joining("\n"));

        assertEquals("Joe Employee,Jan Employee,James T. Employee", employees);
    }
}

5. Conclusão

Neste artigo rápido, vimos algumas maneiras de acessar e ler um recurso do classpath usando Spring, incluindo carregamento rápido e lento e no sistema de arquivos ou em um jar.

E, como sempre, postei todos esses exemplosover on GitHub.