Programmatically reading static resources from my

2019-06-22 13:30发布

问题:

This question already has an answer here:

  • How to find the working folder of a servlet based application in order to load resources 3 answers

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.

回答1:

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:

  • getResourceAsStream() vs FileInputStream


回答2:

Use the getRealPath method of ServletContext.

Ex:

String path = getServletContext().getRealPath("WEB-INF/static/img/myfile.jpeg");


回答3:

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 .



回答4:

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.