Greifen Sie auf eine Datei über den Klassenpfad in einer Spring-Anwendung zu

Greifen Sie in einer Spring-Anwendung über den Klassenpfad auf eine Datei zu

1. Einführung

In diesem Lernprogramm werden verschiedene Möglichkeiten gezeigt, wie Sie mit Spring auf den Inhalt einer Datei zugreifen und diese laden können, die sich im Klassenpfad befindet.

Weitere Lektüre:

Ein Leitfaden zum ResourceBundle

Es ist immer schwierig, mehrsprachige Anwendungen zu warten und zu erweitern. In diesem Artikel wird erläutert, wie Sie mit dem ResourceBundle mit den Sorten umgehen, die auftreten, wenn Sie den gleichen Inhalt für verschiedene Kulturen bereitstellen müssen.

Read more

Laden Sie im Frühjahr eine Ressource als Zeichenfolge

Erfahren Sie, wie Sie den Inhalt einer Ressourcendatei als String in unsere Beans einfügen. Die Ressourcenklasse von Spring macht dies sehr einfach.

Read more

2. Verwenden vonResource

DieResource -Sinterschnittstelle hilft bei der Zusammenfassung des Zugriffs auf Ressourcen auf niedriger Ebene. Tatsächlich unterstützt es den einheitlichen Umgang mit allen Arten von Dateiressourcen.

Schauen wir uns zunächst verschiedene Methoden an, um eineResource-Instanz zu erhalten.

2.1. Manuell

Für den Zugriff auf eine Ressource über den Klassenpfad können wir einfachClassPathResource verwenden:

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

Standardmäßig entferntClassPathResource einige Boilerplates für die Auswahl zwischen dem Kontextklassenlader des Threads und dem Standardsystemklassenlader.

Wir können jedoch auch den Classloader angeben, der entweder direkt verwendet werden soll:

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

Oder indirekt durch eine bestimmte Klasse:

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

Beachten Sie, dass wir vonResource leicht zu Java-Standarddarstellungen wieInputStream orFile springen können.

Eine weitere Bemerkung ist, dass die obige Methode nur für absolute Pfade funktioniert. Wenn Sie einen relativen Pfad angeben möchten, können Sie ein zweitesclass-Argument übergeben. Der Pfad wird relativ zu dieser Klasse sein:

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

Der obige Dateipfad ist relativ zurExample-Klasse.

2.2. Verwenden von@Value

Wir können auchResource mit@Value injizieren:

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

Und@Value unterstützt auch andere Präfixe wiefile: undurl:.

2.3. ResourceLoader verwenden

Oder wenn wir unsere Ressource träge laden möchten, können wirResourceLoader verwenden:

@Autowired
ResourceLoader resourceLoader;

Und dann rufen wir unsere Ressource mitgetResource ab:

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

Beachten Sie auch, dassResourceLoader von allen konkretenApplicationContexts implementiert wird, was bedeutet, dass wir uns auch einfach aufApplicationContext if verlassen können, das besser zu unserer Situation passt:

ApplicationContext context;

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

3. Verwenden vonResourceUtils

Als Einschränkung gibt es eine andere Möglichkeit, Ressourcen im Frühjahr abzurufen, aberResourceUtils Javadoc ist klar, dass die Klasse hauptsächlich für den internen Gebrauch bestimmt ist.

Wenn wir Verwendungen vonResourceUtils ehen, sin unser Code:

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

Wir sollten die Begründung sorgfältig alsit’s probably better to use one of the standard approaches above betrachten.

4. Ressourcendaten lesen

Sobald wir einResource, haben, können wir den Inhalt leicht lesen. Wie wir bereits besprochen haben, können wir leicht eineFile- oder eineInputStream-Referenz ausResource erhalten.

Stellen wir uns vor, wir haben die folgende Dateidata/employees.dat im Klassenpfad:

Joe Employee,Jan Employee,James T. Employee

4.1. Lesen alsFile

Jetzt können wir den Inhalt lesen, indem wirgetFile: aufrufen

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

Beachten Sie jedoch, dass dieser Ansatzexpects the resource to be present in the filesystem and not within a jar file. ist

4.2. Lesen alsInputStream

Nehmen wir jedoch an, dass sich unsere Ressourceisin einem Glas befindet.

Dann können wir stattdessen einResource alsInputStream lesen:

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

In diesem kurzen Artikel haben wir einige Möglichkeiten gesehen, wie Sie mit Spring über den Klassenpfad auf eine Ressource zugreifen und diese lesen können, einschließlich des eifrigen und verzögerten Ladens und im Dateisystem oder in einem Glas.

Und wie immer habe ich alle diese Beispieleover on GitHub veröffentlicht.