Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedded Tomcat not serving static content

I'm using the following (based on this) to create an embedded Tomcat server:

File catalinaHome = new File(".");
File webAppDir = new File("web");

Embedded server = new Embedded();
server.setCatalinaHome(catalinaHome.getAbsolutePath());

Context rootContext = server.createContext("", webAppDir.getAbsolutePath());
rootContext.setParentClassLoader(Thread.currentThread().getContextClassLoader());

Host localHost = server.createHost("localhost", webAppDir.getAbsolutePath());
localHost.addChild(rootContext);

Engine engine = server.createEngine();
engine.setName("localEngine");
engine.addChild(localHost);
engine.setDefaultHost(localHost.getName());
server.addEngine(engine);

Connector http = server.createConnector((InetAddress) null, 8080, false);
server.addConnector(http);

server.setAwait(true);
server.start();

The web directory has static content (index.html, etc.) as well as a WEB-INF directory with servlet descriptors like web.xml. This is starting without exception and the servlets defined in web.xml work, but static content like index.html aren't working.

I'm confused: what am I missing to get the static content handled?

like image 365
Alan Krueger Avatar asked Jun 14 '11 20:06

Alan Krueger


People also ask

Can Tomcat serve static files?

Tomcat will serve any static content from a WAR file using the DefaultServlet.

What is the advantage of having an embedded Tomcat server?

Embedded Tomcat offers a way to package Java web applications that is consistent with a microservices-based approach to software development. It also makes it easier to distribute Java web applications through Docker containers and manage them through a container orchestration service, such as Kubernetes or OpenShift.

Can we use embedded Tomcat in production?

Yes. It's the same tomcat, but in library form. So you are responsible for configuration and other things that the standalone tomcat provides. Also you don't have to use tomcat.

Does Tomcat have spring embedded?

Many Spring Boot starters include default embedded containers. For servlet stack applications, the spring-boot-starter-web includes Tomcat by including spring-boot-starter-tomcat , but you can use spring-boot-starter-jetty or spring-boot-starter-undertow instead.


2 Answers

You need to define the default servlet. It's the one responsible for serving static content. This can be done by either explicitly declaring it in your webapp's /WEB-INF/web.xml the same way as Tomcat's own regular /conf/web.xml is doing, or in the following declarative manner for embedded Tomcat:

// Define DefaultServlet.
Wrapper defaultServlet = rootContext.createWrapper();
defaultServlet.setName("default");
defaultServlet.setServletClass("org.apache.catalina.servlets.DefaultServlet");
defaultServlet.addInitParameter("debug", "0");
defaultServlet.addInitParameter("listings", "false");
defaultServlet.setLoadOnStartup(1);
rootContext.addChild(defaultServlet);
rootContext.addServletMapping("/", "default");

You'd probably also like to do the same for the JSP servlet so that you can also use JSPs:

// Define JspServlet.
Wrapper jspServlet = rootContext.createWrapper();
jspServlet.setName("jsp");
jspServlet.setServletClass("org.apache.jasper.servlet.JspServlet");
jspServlet.addInitParameter("fork", "false");
jspServlet.addInitParameter("xpoweredBy", "false");
jspServlet.setLoadOnStartup(2);
rootContext.addChild(jspServlet);
rootContext.addServletMapping("*.jsp", "jsp");
like image 106
BalusC Avatar answered Oct 12 '22 08:10

BalusC


Instead of configuring the wrappers like BalusC showed, you can also use this one-liner which does (almost) exactly the same:

Tomcat.initWebappDefaults(rootContext);

Add this line somewhere before you start your server. Tested with JDK1.7 and Tomcat 7.0.50.

Note: It additionally adds welcome files and some MIME Type mappings. The method looks like following:

public static void initWebappDefaults(Context ctx) {
        // Default servlet 
        Wrapper servlet = addServlet(
                ctx, "default", "org.apache.catalina.servlets.DefaultServlet");
        servlet.setLoadOnStartup(1);
        servlet.setOverridable(true);

        // JSP servlet (by class name - to avoid loading all deps)
        servlet = addServlet(
                ctx, "jsp", "org.apache.jasper.servlet.JspServlet");
        servlet.addInitParameter("fork", "false");
        servlet.setLoadOnStartup(3);
        servlet.setOverridable(true);

        // Servlet mappings
        ctx.addServletMapping("/", "default");
        ctx.addServletMapping("*.jsp", "jsp");
        ctx.addServletMapping("*.jspx", "jsp");

        // Sessions
        ctx.setSessionTimeout(30);

        // MIME mappings
        for (int i = 0; i < DEFAULT_MIME_MAPPINGS.length;) {
            ctx.addMimeMapping(DEFAULT_MIME_MAPPINGS[i++],
                    DEFAULT_MIME_MAPPINGS[i++]);
        }

        // Welcome files
        ctx.addWelcomeFile("index.html");
        ctx.addWelcomeFile("index.htm");
        ctx.addWelcomeFile("index.jsp");
    }
like image 35
Chris Avatar answered Oct 12 '22 08:10

Chris