27

I am trying to get hold of a file ( or a directory ) under /WEB-INF/.../

outside of a request. I need it in a bean loaded at server startup.

All solutions I can find either wants an XML file using ClassPathXmlApplicationContext or a request to get the servlet context or using the current executing class. Seems ugly to me.

How can I get a File("/WEB-INF/myDir/"). There has to be a way, no!?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
mjs
  • 21,431
  • 31
  • 118
  • 200

7 Answers7

49

As long as your bean is declared in web application context you can obtain an instance of ServletContext (using ServletContextAware, or by autowiring).

Then you can access files in webapp directory either directly (getResourceAsStream(), getRealPath()), or using ServletContextResource.

EDIT by momo:

@Autowired
ServletContext servletContext;

... myMethod() { 
     File rootDir = new File( servletContext.getRealPath("/WEB-INF/myDIR/") );
}
mjs
  • 21,431
  • 31
  • 118
  • 200
axtavt
  • 239,438
  • 41
  • 511
  • 482
  • 2
    +1 for `servletContext.getRealPath("/WEB-INF/myDIR/")` – bizzr3 Oct 11 '14 at 10:13
  • The solution contributed by @mahesh just below is much better, because the Service Layer shouldn't have dependencies from the Web Layer. ServletContext only should be perform in Controllers and something like that. – Dani Aug 12 '15 at 06:43
  • 1
    Plus, getRealPath method may return null depending on which application server and/or the application has been deployed such as a .war in weblogic. – Philippe Gioseffi Jan 11 '16 at 18:05
11

I use Spring DefaultResourceLoader and Resource to read inside WEB-INF or any resources in a *.jar file. Work like a charm. Good luck!

import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;

public static void myFunction() throws IOException {
    final DefaultResourceLoader loader = new DefaultResourceLoader();               
    LOGGER.info(loader.getResource("classpath:META-INF/resources/img/copyright.png").exists());             
    Resource resource = loader.getResource("classpath:META-INF/resources/img/copyright.png");           
    BufferedImage watermarkImage = ImageIO.read(resource.getFile());
}
Lucky
  • 16,787
  • 19
  • 117
  • 151
  • 2
    `DefaultResourceLoader` can't read inside of WEB-INF, you will need `ServletContextResource` for this – Kirill Nov 10 '16 at 11:51
  • @Derp Could you please provide more information about how to implement ServletContextResource in Service Layer? Thanks – Doston Oct 31 '19 at 20:33
3
ClassLoader classLoader = getClass().getClassLoader();
File file = new File(classLoader.getResource("files/test.xml").getFile());

"files" folder should be child of "main/resources" folder

Lucky
  • 16,787
  • 19
  • 117
  • 151
Murali Krish
  • 65
  • 1
  • 11
2

You can use classpath resource if the file is located in the WEB_INF\classes directory. Which is where any files in your src/main/resources directory will be copied to using a normal maven build ...

import org.springframework.core.io.Resource
...
final Resource yourfile = new ClassPathResource( "myfile.txt");
NimChimpsky
  • 46,453
  • 60
  • 198
  • 311
0

This is how you can do it if you just want to access it from a Service (not through ServletContext):

    final DefaultResourceLoader loader = new DefaultResourceLoader();
    Resource resource = loader.getResource("classpath:templates/mail/sample.png");
    File myFile = resource.getFile();

Note that the last line may throw IOException so you need to catch / rethrow

Note, that the file is here: src\main\resources\templates\mail\sample.png

ACV
  • 9,964
  • 5
  • 76
  • 81
-1

Not completely related to your question, but... Here is some universal sulution i used to load properties from anywhere in web application like Spring does it (supporting WEB-INF/..., classpath:..., file:...). Is is based on using ServletContextResourcePatternResolver. You will need ServletContext.

private static Properties loadPropsTheSpringWay(ServletContext ctx, String propsPath) throws IOException {
    PropertiesFactoryBean springProps = new PropertiesFactoryBean();
    ResourcePatternResolver resolver = new ServletContextResourcePatternResolver(ctx);
    springProps.setLocation(resolver.getResource(propsPath));
    springProps.afterPropertiesSet();
    return springProps.getObject();
}

I used the above method in my custom servlet context listener while conext was not yet loaded.

Kirill
  • 6,762
  • 4
  • 51
  • 81
-1
request.getSession().getServletContext().getResourceAsStream("yourfile.pdf");
gene b.
  • 10,512
  • 21
  • 115
  • 227