Accéder à un fichier depuis le classpath dans une application Spring

Accéder à un fichier à partir du classpath dans une application Spring

1. introduction

Dans ce didacticiel, nous allons voir différentes façons d'accéder et de charger le contenu d'un fichier qui se trouve sur le chemin de classe à l'aide de Spring.

Lectures complémentaires:

Un guide du ResourceBundle

Il est toujours difficile de maintenir et d’étendre des applications multilingues. Cet article explique comment utiliser le ResourceBundle pour faire face aux variétés qui apparaissent lorsque vous devez fournir le même contenu à différentes cultures.

Read more

Charger une ressource sous forme de chaîne au printemps

Apprenez à injecter le contenu d'un fichier de ressources dans nos beans sous forme de chaîne, la classe Ressource de Spring rendant cela très facile.

Read more

2. Utilisation deResource

L'interfaceResource aide à extraire l'accès aux ressources de bas niveau. En fait, il prend en charge la gestion de toutes sortes de ressources de fichiers de manière uniforme.

Commençons par examiner différentes méthodes pour obtenir une instanceResource.

2.1. Manuellement

Pour accéder à une ressource depuis le classpath, nous pouvons simplement utiliserClassPathResource:

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

Par défaut,ClassPathResource supprime certains passe-partout pour sélectionner entre le chargeur de classe de contexte du thread et le chargeur de classe système par défaut.

Cependant, nous pouvons également indiquer au chargeur de classe d'utiliser directement:

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

Ou indirectement via une classe spécifiée:

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

Notez qu'à partir deResource, nous pouvons facilement passer aux représentations standard Java commeInputStream orFile.

Une autre chose à noter ici est que la méthode ci-dessus ne fonctionne que pour les chemins absolus. Si vous souhaitez spécifier un chemin relatif, vous pouvez passer un deuxième argumentclass. Le chemin sera relatif à cette classe:

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

Le chemin du fichier ci-dessus est relatif à la classeExample.

2.2. Utilisation de@Value

On peut aussi injecter unResource avec@Value:

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

Et@Value prend également en charge d'autres préfixes, commefile: eturl:.

2.3. Utilisation de ResourceLoader

Ou, si nous voulons charger paresseusement notre ressource, nous pouvons utiliserResourceLoader:

@Autowired
ResourceLoader resourceLoader;

Et puis nous récupérons notre ressource avecgetResource:

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

Notez également queResourceLoader est implémenté par tous lesApplicationContext concrets, ce qui signifie que nous pouvons aussi simplement dépendre deApplicationContext if qui convient mieux à notre situation:

ApplicationContext context;

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

3. Utilisation deResourceUtils

En guise de mise en garde, il existe un autre moyen de récupérer des ressources dans Spring, mais leResourceUtils Javadoc est clair que la classe est principalement à usage interne.

Si nous voyons les utilisations deResourceUtils in notre code:

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

Nous devons examiner attentivement la justification enit’s probably better to use one of the standard approaches above.

4. Lecture des données de ressources

Une fois que nous avons unResource, it, il est facile pour nous de lire le contenu. Comme nous l'avons déjà discuté, nous pouvons facilement obtenir une référenceFile ouInputStream à partir desResource.

Imaginons que nous ayons le fichier suivant,data/employees.dat, sur le chemin de classe:

Joe Employee,Jan Employee,James T. Employee

4.1. Lecture enFile

Maintenant, nous pouvons lire son contenu en appelantgetFile:

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

Cependant, notez que cette approcheexpects the resource to be present in the filesystem and not within a jar file.

4.2. Lecture enInputStream

Disons, cependant, que notre ressourceis dans un pot.

Ensuite, nous pouvons lire à la place unResource comme unInputStream:

@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. Conclusion

Dans cet article rapide, nous avons vu quelques façons d'accéder et de lire une ressource à partir du chemin de classe à l'aide de Spring, y compris le chargement hâtif et paresseux et sur le système de fichiers ou dans un fichier jar.

Et, comme toujours, j’ai publié tous ces exemplesover on GitHub.