Accedi a un file dal Classpath in un'applicazione Spring

1. Introduzione

In questo tutorial vedremo vari modi per accedere e caricare il contenuto di un file che si trova nel classpath usando Spring.

2. Utilizzo della risorsa

L' interfaccia delle risorse aiuta ad astrarre l'accesso alle risorse di basso livello. In effetti, supporta la gestione di tutti i tipi di risorse di file in modo uniforme.

Iniziamo esaminando vari metodi per ottenere un'istanza di risorsa .

2.1. Manualmente

Per accedere a una risorsa dal classpath, possiamo semplicemente usare ClassPathResource :

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

Per impostazione predefinita, ClassPathResource rimuove alcuni boilerplate per la selezione tra il classloader di contesto del thread e il classloader di sistema predefinito.

Tuttavia, possiamo anche indicare il classloader da utilizzare direttamente:

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

O indirettamente attraverso una classe specificata:

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

Nota che da Resource , possiamo facilmente passare a rappresentazioni standard Java come InputStream o File .

Un'altra cosa da notare qui è che il metodo sopra funziona solo per i percorsi assoluti. Se vuoi specificare un percorso relativo, puoi passare un secondo argomento di classe . Il percorso sarà relativo a questa classe:

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

Il percorso del file sopra è relativo alla classe Example .

2.2. Utilizzando @Value

Possiamo anche iniettare una risorsa con @Value :

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

E @Value supporta altri prefissi, anche, come il file: e url: .

2.3. Utilizzando ResourceLoader

Oppure, se vogliamo caricare pigramente la nostra risorsa, possiamo usare ResourceLoader :

@Autowired ResourceLoader resourceLoader;

E poi recuperiamo la nostra risorsa con getResource :

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

Nota anche che ResourceLoader è implementato da tutti gli ApplicationContext concreti , il che significa che possiamo anche semplicemente dipendere da ApplicationContext se questo si adatta meglio alla nostra situazione:

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

3. Utilizzo di ResourceUtils

Come avvertimento, c'è un altro modo per recuperare le risorse in primavera, ma ResourceUtils Javadoc è chiaro che la classe è principalmente per uso interno.

Se vediamo gli usi di ResourceUtils nel nostro codice:

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

Dovremmo considerare attentamente la logica in quanto è probabilmente meglio utilizzare uno degli approcci standard sopra .

4. Lettura dei dati delle risorse

Una volta che abbiamo una risorsa, è facile per noi leggere i contenuti. Come abbiamo già discusso, possiamo facilmente ottenere un file o un riferimento InputStream dalla risorsa .

Immaginiamo di avere il seguente file, data / dipendenti.dat , sul classpath :

Joe Employee,Jan Employee,James T. Employee

4.1. Leggere come file

Ora possiamo leggerne il contenuto chiamando 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); }

Tuttavia, si noti che questo approccio prevede che la risorsa sia presente nel file system e non all'interno di un file jar.

4.2. Lettura come InputStream

Diciamo, però, che la nostra risorsa sia all'interno di un barattolo.

Quindi, possiamo invece leggere una risorsa come 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. conclusione

In questo rapido articolo, abbiamo visto alcuni modi per accedere e leggere una risorsa dal classpath usando Spring, incluso il caricamento ansioso e lento e sul filesystem o in un jar.

E, come sempre, ho pubblicato tutti questi esempi su GitHub.