Jak programowo uzyskać ścieżkę katalogu zasobów

86

Mam następujący układ katalogu:

  • src
    • Główny
      • Jawa
      • zasoby
        • sql (skrypty do bazy danych)
        • sprężyna (konfiguracja)
      • Aplikacja internetowa

W klasie ServletContextListener chcę uzyskać dostęp do plików w katalogu SQL i wyświetlić je. Zasadniczo mój problem dotyczy ścieżki, ponieważ wiem, że wyświetlanie plików w katalogu w pigułce to:

File folder = new File(path);
File[] listOfFiles = folder.listFiles();

Może mógłbym użyć ServletContextEventObiektu, aby spróbować zbudować ścieżkę doresources/sql

public void contextInitialized(ServletContextEvent event) {
    event.getServletContext(); //(getRealPath etc.)
}

Czy istnieje coś, co wyznaczy tę ścieżkę w sposób względny, nie zakodowany na stałe? Coś takiego new File("classpath:sql")(najlepiej wiosna, jeśli to możliwe) lub co powinienem zrobić z serwletem, aby wskazać resources/sql?

yamilmedina
źródło
Istnieją trzy warianty rozwiązania, w zależności od sytuacji: stackoverflow.com/a/56327069/715269
Gangnus

Odpowiedzi:

69

Zakładam, że zawartość src/main/resources/jest kopiowana do WEB-INF/classes/twojego .war w czasie kompilacji. Jeśli tak jest, możesz po prostu to zrobić (podstawiając rzeczywiste wartości dla nazwy klasy i ładowanej ścieżki).

URL sqlScriptUrl = MyServletContextListener.class
                       .getClassLoader().getResource("sql/script.sql");
Dev
źródło
Dzięki!! to zadziałało dla mnie, z tym adresem URL, następnie buduję ścieżkę dla nowego pliku i ostatecznie pobieram pliki w tym katalogu.
yamilmedina
2
Nie potrzebujesz pliku. Masz już adres URL. Nie możesz nawet założyć, że w ogóle istnieje plik lub katalog. Wojna mogła nie zostać rozpakowana.
Markiz Lorne
Co oznacza tutaj MyServletContextListener?
Tejesh Raut
@TejeshRaut Jest to miejsce na klasę, która implementuje javax.servlet.ServletContextListener. Użyłem tego jako przykładu, ponieważ pytanie zawierało fragment, z contextInitialized którego jest metoda zdefiniowana przez ServletContextListenerinterfejs.
Dev
60

Wreszcie to, co zrobiłem:

private File getFileFromURL() {
    URL url = this.getClass().getClassLoader().getResource("/sql");
    File file = null;
    try {
        file = new File(url.toURI());
    } catch (URISyntaxException e) {
        file = new File(url.getPath());
    } finally {
        return file;
    }
}

...

File folder = getFileFromURL();
File[] listOfFiles = folder.listFiles();
yamilmedina
źródło
11
Czy na pewno używasz "/sql"jako parametru? Mam problemy z początkowym ukośnikiem, Zamiast tego "sql"działa.
Abdull
2
Pamiętaj, że możesz uzyskać inny adres URL za pomocą this.getClass (). GetResource ("/ sql"));
ShadowGames
To nie zadziała na wszystkich kontenerach. Na przykład Tomcat.
Markiz Lorne
16
import org.springframework.core.io.ClassPathResource;

...

File folder = new ClassPathResource("sql").getFile();
File[] listOfFiles = folder.listFiles();

Warto zauważyć, że ograniczy to opcje wdrażania, ClassPathResource.getFile()działa tylko wtedy, gdy kontener eksplodował (rozpakował) plik wojenny.

samlewis
źródło
6

Po prostu użyj klasy com.google.common.io.Resources . Przykład:

 URL url = Resources.getResource("file name")

Następnie masz metody takie jak: .getContent (), .getFile (), .getPath () itp.

grep
źródło
1
Czy obsługują również pobieranie zasobów podczas wykonywania kodu z pliku jar?
Displee