I have a Java web application running on Tomcat. I want to load static images that will be shown both on the Web UI and in PDF files generated by the application. Also new images will be added and saved by uploading via the Web UI.
It's not a problem to do this by having the static data stored within the the web container but storing and loading them from outside the web container is giving me headache.
I'd prefer not to use a separate web server like Apache for serving the static data at this point. I also don't like the idea of storing the images in binary in a database.
I've seen some suggestions like having the image directory being a symbolic link pointing to a directory outside the web container, but will this approach work both on Windows and *nix environments?
Some suggest writing a filter or a servlet for handling the image serving but those suggestions have been very vague and high-level without pointers to more detailed information on how to accomplish this.
If you adhere the *nix filesystem path rules (i.e. you use exclusively forward slashes as in
/path/to/files
), then it will work on Windows as well without the need to fiddle around with uglyFile.separator
string-concatenations. It would however only be scanned on the same working disk as from where this command is been invoked. So if Tomcat is for example installed onC:
then the/path/to/files
would actually point toC:\path\to\files
.If the files are all located outside the webapp, and you want to have Tomcat's
DefaultServlet
to handle them, then all you basically need to do in Tomcat is to add the following Context element to/conf/server.xml
inside<Host>
tag:This way they'll be accessible through
http://example.com/files/...
. GlassFish/Payara configuration example can be found here and WildFly configuration example can be found here.If you want to have control over reading/writing files yourself, then you need to create a
Servlet
for this which basically just gets anInputStream
of the file in flavor of for exampleFileInputStream
and writes it to theOutputStream
of theHttpServletResponse
.On the response, you should set the
Content-Type
header so that the client knows which application to associate with the provided file. And, you should set theContent-Length
header so that the client can calculate the download progress, otherwise it will be unknown. And, you should set theContent-Disposition
header toattachment
if you want a Save As dialog, otherwise the client will attempt to display it inline. Finally just write the file content to the response output stream.Here's a basic example of such a servlet:
When mapped on an
url-pattern
of for example/files/*
, then you can call it byhttp://example.com/files/image.png
. This way you can have more control over the requests than theDefaultServlet
does, such as providing a default image (i.e.if (!file.exists()) file = new File("/path/to/files", "404.gif")
or so). Also using therequest.getPathInfo()
is preferred aboverequest.getParameter()
because it is more SEO friendly and otherwise IE won't pick the correct filename during Save As.You can reuse the same logic for serving files from database. Simply replace
new FileInputStream()
byResultSet#getInputStream()
.Hope this helps.
See also:
You can do it by putting your images on a fixed path (for example: /var/images, or c:\images), add a setting in your application settings (represented in my example by the Settings.class), and load them like that, in a
HttpServlet
of yours:Or if you want to manipulate the image:
then the html code would be
<img src="imageServlet?imageName=myimage.png" />
Of course you should think of serving different content types - "image/jpeg", for example based on the file extension. Also you should provide some caching.
In addition you could use this servlet for quality rescaling of your images, by providing width and height parameters as arguments, and using
image.getScaledInstance(w, h, Image.SCALE_SMOOTH
), considering performance, of course.Requirement : Accessing the static Resources (images/videos., etc.,) from outside of WEBROOT directory or from local disk
Step 1 :
Create a folder under webapps of tomcat server., let us say the folder name is myproj
Step 2 :
Under myproj create a WEB-INF folder under this create a simple web.xml
code under web.xml
Directory Structure for the above two steps
Step 3:
Now create a xml file with name myproj.xml under the following location
CODE in myproj.xml:
Step 4:
4 A) Now create a folder with name myproj in E drive of your hard disk and create a new
folder with name images and place some images in images folder
(e:myproj\images\)
Let us suppose myfoto.jpg is placed under
e:\myproj\images\myfoto.jpg
4 B) Now create a folder with name WEB-INF in
e:\myproj\WEB-INF
and create a web.xml in WEB-INF folderCode in web.xml
Step 5:
Now create a .html document with name index.html and place under e:\myproj
CODE under index.html Welcome to Myproj
The Directory Structure for the above Step 4 and Step 5 is as follows
Step 6:
Now start the apache tomcat server
Step 7:
open the browser and type the url as follows
then u display the content which is provided in index.html
Step 8:
To Access the Images under your local hard disk (outside of webroot)
If you decide to dispatch to
FileServlet
then you will also needallowLinking="true"
incontext.xml
in order to allowFileServlet
to traverse the symlinks.See http://tomcat.apache.org/tomcat-6.0-doc/config/context.html
Add to server.xml :
Enable dir file listing parameter in web.xml :
Read the InputStream of a file and write it to
ServletOutputStream
for sending binary data to the client.Result the URL directly to the
src
attibute.