100

I've got a file in my war/WEB-INF folder of my app engine project. I read in the FAQs that you can read a file from there in a servlet context. I don't know how to form the path to the resource though:

/war/WEB-INF/test/foo.txt

How would I construct my path to that resource to use with File(), just as it looks above?

Thanks

Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
user291701
  • 38,411
  • 72
  • 187
  • 285

3 Answers3

144

There's a couple ways of doing this. As long as the WAR file is expanded (a set of files instead of one .war file), you can use this API:

ServletContext context = getContext();
String fullPath = context.getRealPath("/WEB-INF/test/foo.txt");

http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/ServletContext.html#getRealPath(java.lang.String)

That will get you the full system path to the resource you are looking for. However, that won't work if the Servlet Container never expands the WAR file (like Tomcat). What will work is using the ServletContext's getResource methods.

ServletContext context = getContext();
URL resourceUrl = context.getResource("/WEB-INF/test/foo.txt");

or alternatively if you just want the input stream:

InputStream resourceContent = context.getResourceAsStream("/WEB-INF/test/foo.txt");

http://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/ServletContext.html#getResource(java.lang.String)

The latter approach will work no matter what Servlet Container you use and where the application is installed. The former approach will only work if the WAR file is unzipped before deployment.

EDIT: The getContext() method is obviously something you would have to implement. JSP pages make it available as the context field. In a servlet you get it from your ServletConfig which is passed into the servlet's init() method. If you store it at that time, you can get your ServletContext any time you want after that.

Berin Loritsch
  • 11,400
  • 4
  • 30
  • 57
  • 3
    It's worth pointing out that I needed to put an initial / in the path to get this to work, like this: context.getResourceAsStream("/WEB-INF/test/foo.txt"); – Mick Sear Jun 16 '11 at 15:06
  • Just to follow up, yes you can use the path just like that, it works. – user291701 Dec 03 '10 at 02:53
  • From Java Docs: "The path must begin with a / and is interpreted as relative to the current context root" for ServletContext.getResource and ServletContext.getResourceAsStream: ". The path must be specified according to the rules given in getResource. " – Koray Tugay Apr 27 '14 at 16:45
  • Just a note: the example code was updated back in 2011 after Mick Sear mentioned that in his comment. – Berin Loritsch Feb 09 '15 at 12:18
  • 1
    Doesn't work as simple on appengine, as the question is tagged for. – Renascienza Jun 16 '16 at 01:15
  • 2
    It was marked as the correct answer 6 years ago. Either Google changed the app engine API or there is a bug in your deployment. If you are running a standard Servlet, you should be able to use the `context.getResourceAsStream()` variation. – Berin Loritsch Jun 16 '16 at 02:06
  • 2
    this seems good, but i am using java 1.8 and getContext() doesn't exist by default, which jar file is needed to use it? – f1wade Sep 20 '16 at 14:46
  • 3
    ServletContext is part of the `javax.servlet` package of your J2EE libraries. You get a reference to it from the servlet class (i.e. what extends `java.servlet.GenericServlet`). BTW, GenericServlet now has a method to `getServletContext()` http://docs.oracle.com/javaee/6/api/javax/servlet/GenericServlet.html#getServletContext() – Berin Loritsch Sep 20 '16 at 18:25
5

Now with Java EE 7 you can find the resource more easily with

InputStream resource = getServletContext().getResourceAsStream("/WEB-INF/my.json");

https://docs.oracle.com/javaee/7/api/javax/servlet/GenericServlet.html#getServletContext--

Daniel De León
  • 13,196
  • 5
  • 87
  • 72
3

I know this is late, but this is how I normally do it,

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();           
InputStream stream = classLoader.getResourceAsStream("../test/foo.txt");
eunelyky
  • 69
  • 7