How can i use Tomcat to serve image files from a public folder outside webapps? I dont want to use a 2nd Apache fileserver on a different port since the image files are part of the same app. And i dont want to create a symlink to the public folder inside webapps since my app is deployed as a war file....Is there a simpler solution similar to using default servlet for static content inside webapps, for static content outside outside webapps
-
https://www.moreofless.co.uk/static-content-web-pages-images-tomcat-outside-war/ – Taras Melnyk Jun 15 '18 at 08:40
8 Answers
This is the way I did it and it worked fine for me. (done on Tomcat 7.x)
Add a <context>
to the tomcat/conf/server.xml
file.
Windows example:
<Context docBase="c:\Documents and Settings\The User\images" path="/project/images" />
Linux example:
<Context docBase="/var/project/images" path="/project/images" />
Like this (in context):
<Server port="8025" shutdown="SHUTDOWN">
...
<Service name="Catalina">
...
<Engine defaultHost="localhost" name="Catalina">
...
<Host appBase="webapps"
autoDeploy="false" name="localhost" unpackWARs="true"
xmlNamespaceAware="false" xmlValidation="false">
...
<!--MAGIC LINE GOES HERE-->
<Context docBase="/var/project/images" path="/project/images" />
</Host>
</Engine>
</Service>
</Server>
In this way, you should be able to find the files (e.g. /var/project/images/NameOfImage.jpg
) under:
http://localhost:8080/project/images/NameOfImage.jpg

- 1,697
- 1
- 21
- 41

- 2,304
- 1
- 29
- 28
-
This worked perfectly for me with Tomcat 7 on Windows Server 2008. it was also by far the simplest solution I found. For the record, if you use the Tomcat manager, the value put in the "path" attribute of the "Context" element will appear as a running application. Thank. – Night Owl Dec 03 '14 at 05:51
-
1
-
1
-
1
-
-
2
-
This is working fine we have tested and wanted the same for our application – Raj Sharma Sep 30 '16 at 12:33
-
For more info please read: https://www.moreofless.co.uk/static-content-web-pages-images-tomcat-outside-war/ – Mahsa2 Nov 24 '16 at 22:33
-
i am getting this error after do something like this 01-Mar-2017 03:31:55.091 WARNING [localhost-startStop-1] org.apache.catalina.core.NamingContextListener.addResource Failed to register in JMX: javax.naming.NamingException: Unable to load class: com.mysql.jdbc.Driver from ClassLoader:java.net.URLClassLoader@1fb3ebeb;ClassLoader:ParallelWebappClassLoader context: gambarku delegate: false ----------> Parent Classloader: java.net.URLClassLoader@1fb3ebeb – Mar 01 '17 at 03:34
-
7
-
1@delkant This does not work, if I want to update (delete, add) some image during tomcat is on. I will get only images, which was there before serever startup. – Gleb S Apr 24 '17 at 13:32
-
1
-
Works! This is how I did it. What I'm trying to figure out now is how do I get the host path using a web application to upload files to it? – yanike Nov 24 '17 at 21:28
-
It's not working in tomcat 9.0. It works till tomcat 8.0. Is there any work around for tomcat 9.0 ? – Bhavin May 29 '18 at 10:55
-
You could have a redirect servlet. In you web.xml you'd have:
<servlet>
<servlet-name>images</servlet-name>
<servlet-class>com.example.images.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>images</servlet-name>
<url-pattern>/images/*</url-pattern>
</servlet-mapping>
All your images would be in "/images", which would be intercepted by the servlet. It would then read in the relevant file in whatever folder and serve it right back out. For example, say you have a gif in your images folder, c:\Server_Images\smilie.gif. In the web page would be <img src="http:/example.com/app/images/smilie.gif"...
. In the servlet, HttpServletRequest.getPathInfo()
would yield "/smilie.gif". Which the servlet would find in the folder.

- 60,628
- 22
- 121
- 123
-
51I don't think your answer has made it clear enough that `com.example.images.ImageServlet` is something you will have write yourself. – Ben Page Aug 16 '11 at 15:40
-
2Answer is much like the FileServlet here - http://balusc.blogspot.com/2007/07/fileservlet.html . Thorough solution and informative page so that's what I went with. – Michael K Jul 31 '13 at 21:59
-
-
In Tomcat 7, you can use "aliases" property. From the docs:
This attribute provides a list of external locations from which to load resources for this context. The list of aliases should be of the form "/aliasPath1=docBase1,/aliasPath2=docBase2" where aliasPathN must include a leading '/' and docBaseN must be an absolute path to either a .war file or a directory. A resource will be searched for in the first docBaseN for which aliasPathN is a leading path segment of the resource. If there is no such alias, then the resource will be searched in the usual way. These external locations will not be emptied if the context is un-deployed.

- 3,447
- 1
- 35
- 41
You can deploy an images folder as a separate webapp and define the location of that folder to be anywhere in the file system.
Create a Context element in an XML file in the directory $CATALINA_HOME/conf/[enginename]/[hostname]/
where enginename might be 'Catalina' and hostname might be 'localhost'.
Name the file based on the path URL you want the images to be viewed from, so if your webapp has path 'blog', you might name the XML file blog#images.xml
and so that your images would be visible at example.com/blog/images/
The content of the XML file should be <Context docBase="/filesystem/path/to/images"/>
Be careful not to undeploy this webapp, as that could delete all your images!

- 1,644
- 18
- 25
-
The problem with this solution is that it takes 5-10 seconds for Tomcat to auto-deploy images. – somid3 Jul 02 '12 at 14:35
Instead of configuring Tomcat to redirect requests, use Apache as a frontend with the Apache Tomcat connector so that Apache is only serving static content, while asking tomcat for dynamic content.
Using the JKmount directive (or others) you could specify exactly which requests are sent to Tomcat.
Requests for static content, such as images, would be served directly by Apache, using a standard virtual host configuration, while other requests, defined in the JKMount directive will be sent to Tomcat workers.
I think this implementation would give you the most flexibility and control on the overall application.

- 358
- 3
- 9
-
-
Reading your comment I've just realized I had included a link for some old docs. Am correcting this now. – adilei Jan 07 '09 at 07:05
-
I have handled this using following way # Static files in the examples web app are served by Apache Alias /example var\opt\tomcat\webapps\example JkMount /example/*.jpg ajp13 JkMount /example/*.png ajp13 JkMount /example/*.gif ajp13 – Ganesh Giri Jul 22 '20 at 07:41
After none of solutions based on defining XMLs worked for me, I found this answer very helpful. Took about a minute, and a small code change: I modified this line
this.basePath = getServletContext().getRealPath(getInitParameter("basePath"));
into
this.basePath = getInitParameter("basePath");

- 1
- 1

- 3,632
- 31
- 47
-
I was in the same case, but your answer helped me a lot, Thanks ;) ! – Brahim LAMJAGUAR Jun 08 '16 at 11:32
Many years later, we can do the following with Spring Web MVC, inside our webapp-servlet.xml
file:
<mvc:resources mapping="/static/**" location="/static/" />

- 2,080
- 1
- 15
- 17
-
3As far as I know this does not work if the static content is located in a external directory. – rmoestl Apr 30 '13 at 11:46
This is very simple and straight forward to server the static content from outside webapps folder in tomcat.
Simply edit the server.xml under $CATALINA_HOME/config/server.xml as below and restart the tomcat.
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
**<Context docBase="C:\Ankur\testFiles" path="/companyLogo" />**
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
Add the context element inside the host element with two attribute docBase and path.
1) docBase: represents the hard drive directory 2) path: represents the uri on which you want to serve the static content.
For example:If you have 7.png inside the C:\Ankur\testFiles directory then you can access the 7.png file like below:
http://localhost:8081/companyLogo/7.png
For more details, check the blog

- 963
- 3
- 14
- 21