5

I currently have a bunch of images in my .war file like this.

WAR-ROOT
  -WEB-INF
  -IMAGES
    -image1.jpg
    -image2.jpg
  -index.html

When I generate html via my servlets/jsp/etc I can simple link to

http://host/contextroot/IMAGES/image1.jpg

and

http://host/contextroot/IMAGES/image1.jpg

Not I am writing a servlet that needs to get a filesystem reference to these images (to render out a composite .pdf file in this case). Does anybody have a suggestion for how to get a filesystem reference to files placed in the war similar to how this is?

Is it perhaps a url I grab on servlet initialization? I could obviously have a properties file that explicitly points to the installed directory but I would like to avoid additional configs.

benstpierre
  • 32,833
  • 51
  • 177
  • 288

4 Answers4

14

If you can guarantee that the WAR is expanded, then you can use ServletContext#getRealPath() to convert a relative web path to an absolute disk file system which you can further use in the usual Java IO stuff.

String relativeWebPath = "/IMAGES/image1.jpg";
String absoluteDiskPath = getServletContext().getRealPath(relativeWebPath);
File file = new File(absoluteDiskPath);
InputStream input = new FileInputStream(file);
// ...

However, if you can't guarantee that the WAR is expanded (i.e. all resources are still packaged inside WAR) and you're actually not interested on the absolute disk file system path and all you actually need is just an InputStream out of it, then use getServletContext().getResourceAsStream() instead.

String relativeWebPath = "/IMAGES/image1.jpg";
InputStream input = getServletContext().getResourceAsStream(relativeWebPath);
// ...

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • With your second point, in what case would a .war file not be expanded? AFAIK when you upload a .war file to common servlet containers it unpacks them for you to a working directory. Do you know of a specific case to watch out for? – benstpierre May 06 '11 at 19:20
  • 1
    This is configureable at server level. Most servletcontainers by default unpacks them. But most if not all 3rd party hostings are configured to not do so. The `getRealPath()` will return `null` in such case. After all, if you are actually only interested in the `InputStream`, you should avoid using `getRealPath()` and go ahead with `getResourceAsStream()` on `ServletContext`. – BalusC May 06 '11 at 19:22
  • That is a good solution! – Scarlett Jun 27 '12 at 07:30
5

Use the getRealPath method of ServletContext.

Ex:

String path = getServletContext().getRealPath("WEB-INF/static/img/myfile.jpeg");
Mike Thomsen
  • 36,828
  • 10
  • 60
  • 83
-2

This is relatively straight forward you simply use the class loader to fetch the files from the class plath. :

InputStream is =  YourServlet.class.getClassLoader().getResourceAsStream("IMAGES/img1.jpg");

There are a few other getResoruce classes that are worth looking at. Also you don't have to fetch the class loader through the class variable on your servlet. Any class that you happen to know has been loaded by the container should work .

Karthik Ramachandran
  • 11,925
  • 10
  • 45
  • 53
  • 1
    Unfortunately, the webcontent is not part of the classpath. Only the `/WEB-INF/lib` and `/WEB-INF/classes` are. So this method ain't going to work. – BalusC May 06 '11 at 18:59
-3

If you know the relative location of the files you could ask the runtime about the exact location using

Thread.currentThread().getContextClassLoader().getResource(<relative-path>/<filename>)

This would give you an URL to the location where the specified image can be found. This URL can be used to read the specified file or you can split it to use the different parts of the URL for further processing.

Osiris76
  • 1,234
  • 9
  • 5
  • 2
    Unfortunately, the webcontent is not part of the classpath. Only the `/WEB-INF/lib` and `/WEB-INF/classes` are. So this method ain't going to work. – BalusC May 06 '11 at 18:59