Accéder à un fichier à partir du chemin de classe dans une application Spring

1. Introduction

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

2. Utilisation de la ressource

L' interface Resource permet d'abstraire 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 instance Resource .

2.1. Manuellement

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

public Resource loadEmployeesWithClassPathResource() { 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 à utiliser soit 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 de Resource , nous pouvons facilement passer aux représentations standard Java comme InputStream ou File .

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 argument de classe . Le chemin sera relatif à cette classe:

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

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

2.2. Utiliser @Value

Nous pouvons également injecter une Ressource avec @Value :

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

Et @Value soutient d' autres préfixes, aussi, comme fichier: et url: .

2.3. Utilisation de ResourceLoader

Ou, si nous voulons charger paresseusement notre ressource, nous pouvons utiliser ResourceLoader :

@Autowired ResourceLoader resourceLoader;

Et puis nous récupérons notre ressource avec getResource :

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

Notez également que ResourceLoader est implémenté par tous les ApplicationContext concrets , ce qui signifie que nous pouvons également simplement dépendre d' ApplicationContext si cela convient mieux à notre situation:

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

3. Utilisation de ResourceUtils

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

Si nous voyons des utilisations de ResourceUtils dans notre code:

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

Nous devrions examiner attentivement la justification car il est probablement préférable d'utiliser l'une des approches standard ci-dessus .

4. Lecture des données de ressources

Une fois que nous avons une ressource, il nous est facile de lire le contenu. Comme nous l'avons déjà mentionné, nous pouvons facilement obtenir un fichier ou une référence InputStream à partir de la ressource .

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

Joe Employee,Jan Employee,James T. Employee

4.1. Lire en tant que fichier

Maintenant, nous pouvons lire son contenu en appelant getFile:

@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 approche s'attend à ce que la ressource soit présente dans le système de fichiers et non dans un fichier jar.

4.2. Lire comme InputStream

Disons, cependant, que notre ressource est à l' intérieur d'un pot.

Ensuite, nous pouvons à la place lire une ressource comme un InputStream :

@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 lazy et sur le système de fichiers ou dans un fichier jar.

Et, comme toujours, j'ai posté tous ces exemples sur GitHub.