Como obter o caminho do diretório de recursos de forma programática

86

Tenho o seguinte layout de diretório:

  • src
    • a Principal
      • Java
      • Recursos
        • sql (scripts para banco de dados)
        • mola (configuração)
      • aplicativo web

Em uma classe ServletContextListener, desejo acessar os arquivos no diretório SQL e listá-los. Basicamente, meu problema é com o caminho, porque sei que listar arquivos em um diretório em poucas palavras é:

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

Talvez eu pudesse usar o ServletContextEventobjeto para tentar construir um caminho pararesources/sql

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

Existe algo para definir esse caminho de maneira relativa e não codificada? Algo como new File("classpath:sql")(de preferência spring, se possível) ou o que devo fazer com o servletContext para apontar resources/sql?

yamilmedina
fonte
Existem três variantes de solução, dependendo da situação: stackoverflow.com/a/56327069/715269
Gangnus

Respostas:

69

Estou assumindo que o conteúdo de src/main/resources/é copiado para WEB-INF/classes/dentro de seu .war no momento da construção. Se for esse o caso, você pode apenas fazer (substituindo por valores reais o nome da classe e o caminho que está sendo carregado).

URL sqlScriptUrl = MyServletContextListener.class
                       .getClassLoader().getResource("sql/script.sql");
Dev
fonte
Obrigado!! isso funcionou para mim, com aquela URL, então eu construí o caminho para o novo arquivo e, finalmente, obtenho os arquivos naquele diretório.
yamilmedina
2
Você não precisa do arquivo. Você já tem um URL. Você não pode nem presumir que existe um arquivo ou diretório. O WAR pode não ter sido desempacotado.
Marquês de Lorne
O que MyServletContextListener significa aqui?
Tejesh Raut
@TejeshRaut É um espaço reservado para uma classe que implementa javax.servlet.ServletContextListener. Usei isso como exemplo porque a questão tinha um trecho do contextInitialized qual é um método definido pela ServletContextListenerinterface.
Dev
59

Finalmente, foi isso que eu fiz:

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
fonte
11
Tem certeza de usar "/sql"como parâmetro? Tenho problemas com uma barra inicial, mas "sql"funciona.
Abdull
2
Esteja ciente de que você pode obter uma URL diferente com this.getClass (). GetResource ("/ sql"));
ShadowGames
Isso não funcionará em todos os contêineres. Tomcat, por exemplo.
Marquês de Lorne
16
import org.springframework.core.io.ClassPathResource;

...

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

É importante notar que isso limitará suas opções de implantação, ClassPathResource.getFile()só funciona se o contêiner explodiu (descompactou) seu arquivo war.

Samlewis
fonte
6

Basta usar a classe com.google.common.io.Resources . Exemplo:

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

Depois disso, você tem métodos como: .getContent (), .getFile (), .getPath () etc

grep
fonte
1
Eles também suportam a obtenção de recursos enquanto o código está sendo executado a partir de um arquivo jar?
Displee