How to serve static content from a location on disk, that is outside of the WAR file, using Apache Tomcat 7. This method can be used to serve images, JavaScript, CSS, JSON, PDFs and even static HTML web pages.

Tomcat will serve any static content from a WAR file using the DefaultServlet. This works great for serving files that are bundled with your Java code inside of a WAR file – it’s fast enough for most purposes and it just works, but with one major drawback: you have to re-deploy the WAR file it you want to add or amend a static file. That may work for you but if you are working in a development process where releasing new versions of your app requires sign-offs and rounds of testing then it doesn’t make sense to go through that process just to update a single image file because someone wants a slightly darker blue background on the contact page.

We can be a bit more flexible.

Tomcat can be configured to read files from anywhere on disk and serve them on a specific URL. This configuration is completely separate to your application config – you could, if you wanted, just start Tomcat and have it serve static files from disk with no webapps running. The configuration is in Tomcat’s server.xml configuration file and looks like this (the bit that needs to be added is in red):

      
  <Host appBase="webapps"
           autoDeploy="false" name="localhost" unpackWARs="true"
           xmlNamespaceAware="false" xmlValidation="false">
    ...
    <Context docBase="/home/stuff" path="/static" />

  </Host>

A <Context> element is added inside the <Host> element. Context has two attributes: docBase is the directory on disk that contains your static files and path is the URL that you want to serve the files on.

Make sure that Tomcat has access to read the files in docBase.

Using the example server.xml snippet above, if I had an image in /home/stuff called steve.jpg I would be able to access it via my local Tomcat instance using http://localhost:8080/static/steve.jpg.

Serving static web pages

This method also works for serving HTML web pages and can be a great way to serve unchanging web pages quickly from Tomcat without having to write any Java code.

This works exactly the same as the above image example. Tomcat would serve the /home/stuff/hello.html via http://localhost:8080/static/hello.html.

A quick note about MIME types

Tomcat serves the correct MIME type to the browser for static content when the type is obvious from the name of the file being served – for example steve.jpg is served as a image/jpeg and hello.html is served as text/html.

You may want to serve web pages using clean and SEO-friendly URLs, so instead of http://localhost:8080/static/hello.html you’d have http://localhost:8080/static/hello – Tomcat doesn’t know the MIME type for a file with no extension and so serves hello without a specified type. This is fine most of the time as browsers are smart and realise that hello is an HTML document but if you are serving content to something other than a browser (say someone else’s code is reading your content via an API) then you may need to be careful about MIME types.