110

I have the following directory layout:

  • src
    • main
      • java
      • resources
        • sql (scripts for database)
        • spring (configuration)
      • webapp

Within a ServletContextListener class, I want to access the files under the SQL directory and list them. Basically my problem is with the path, because I know that listing files under a directory in a nutshell is:

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

Maybe I could use the ServletContextEvent Object to try and build a path to resources/sql

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

Does something exist to set that path in a relative, non-hardcoded way? Something like new File("classpath:sql") (preferably spring if possible) or what should I do with the servletContext to point at resources/sql?

doelleri
  • 19,232
  • 5
  • 61
  • 65
yamilmedina
  • 3,315
  • 2
  • 20
  • 28
  • There are three variants of solution, depending on the situation: https://stackoverflow.com/a/56327069/715269 – Gangnus May 27 '19 at 13:33
  • See also [How to get the path of src/test/resources directory in JUnit?](https://stackoverflow.com/questions/28673651/how-to-get-the-path-of-src-test-resources-directory-in-junit) – Vadzim Feb 15 '22 at 02:31

4 Answers4

86

I'm assuming the contents of src/main/resources/ is copied to WEB-INF/classes/ inside your .war at build time. If that is the case you can just do (substituting real values for the classname and the path being loaded).

URL sqlScriptUrl = MyServletContextListener.class
                       .getClassLoader().getResource("sql/script.sql");
Dev
  • 11,919
  • 3
  • 40
  • 53
  • Thanks!! this worked for me, with that URL then I build the Path for the new File, and finally get the files in that directory. – yamilmedina Oct 17 '13 at 15:25
  • 2
    You don't need the File. You already have a URL. You can't even assume there is a file or a directory at all. The WAR may not have been unpacked. – user207421 Oct 18 '13 at 21:24
  • What does MyServletContextListener mean here ? – Tejesh Raut Dec 04 '15 at 10:02
  • @TejeshRaut It is a place holder for a class that implements [`javax.servlet.ServletContextListener`](http://docs.oracle.com/javaee/7/api/javax/servlet/ServletContextListener.html). I used that as an example because the question had a snippet from `contextInitialized` which is a method defined by the `ServletContextListener` interface. – Dev Dec 05 '15 at 01:24
  • For me it was crucial to prepend the path with `classpath:`, so: `"classpath:/sql/script.sql"`. – isgoed Jan 21 '21 at 15:19
76

Finally, this is what I did:

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();
Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
yamilmedina
  • 3,315
  • 2
  • 20
  • 28
19
import org.springframework.core.io.ClassPathResource;

...

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

It is worth noting that this will limit your deployment options, ClassPathResource.getFile() only works if the container has exploded (unzipped) your war file.

samlewis
  • 3,950
  • 27
  • 27
11

Just use com.google.common.io.Resources class. Example:

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

After that you have methods like: .getContent(), .getFile(), .getPath() etc

grep
  • 5,465
  • 12
  • 60
  • 112