Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jetty-dev] Jetty Split File Server combined with a Header Filter

More info:

Joakim Erdfelt / joakim@xxxxxxxxxxx

On Wed, Jun 13, 2018 at 1:44 PM, Joakim Erdfelt <joakim@xxxxxxxxxxx> wrote:
Don't mix ResourceHandler and ServletContextHandler unless you *REALLY* know what you are doing.

Eg: once you enter a ServletContextHandler you are subject to all of the rules for a javax.servlet.ServletContext.  You never exit a ServletContextHandler, and Filters only apply within the request chain within that ServletContext.
A sub-handler like you declared it, is NOT part of the ServletContext, or the request chain in that ServletContext.

A better approach, stay with 1 ServletContextHandler, no ResourceHandler, use the DefaultServlet instead to serve static content (its a MUCH better choice then ResourceHandler anyway).

File codeDocsDir = new File("/tmp/code-docs");
Resource codeDocsResource = Resource.newResource(codeDocsDir);
File userGuideDocsDir = new File("/tmp/user-guide-docs");
Resource userGuideDocsResource = Resource.newResource(userGuideDocsDir);
ResourceCollection resources = new ResourceCollection(codeDocsResource, userGuideDocsResource);

ServletContextHandler handler = new ServletContextHandler();
handler.setBaseResource(resources); // what static content resources are used

FilterHolder frameOptions = new FilterHolder(FRAME_OPTIONS_FILTER);
handler.addFilter(frameOptions, "/*", EnumSet.allOf(DispatcherType.class));

ServletHolder holderDef = new ServletHolder("default", DefaultServlet.class); // what serves the static resources
return handler;

Joakim Erdfelt / joakim@xxxxxxxxxxx

On Wed, Jun 13, 2018 at 1:32 PM, Nathan Gough <returntosender404@xxxxxxxxx> wrote:

I've created a demo application to demonstrate the issue I'm having:

package jetty.demo;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.resource.Resource;
import org.eclipse.jetty.util.resource.ResourceCollection;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import java.util.EnumSet;
public class EmbeddedDocsWebApp
    public EmbeddedDocsWebApp() {
    public static void main(String[] args)
        Server server = new Server();
        ServerConnector connector = new ServerConnector(server);
        String contextPath = "/all-docs";
        jetty.demo.EmbeddedDocsWebApp webApp = new jetty.demo.EmbeddedDocsWebApp();
        ServletContextHandler context = webApp.createDocsWebApp(contextPath);
        catch (Throwable t)
    private ServletContextHandler createDocsWebApp(final String contextPath) {
        try {
            final ResourceHandler resourceHandler = new ResourceHandler();
            final File codeDocsDir = new File("/tmp/code-docs");
            final Resource codeDocsResource = Resource.newResource(codeDocsDir);
            // Load the component documentation working directory
            final File userGuideDocsDir = new File("/tmp/user-guide-docs");
            final Resource userGuideDocsResource = Resource.newResource(userGuideDocsDir);
            // Create resources for three docs locations - User Guides, Processor Docs, NiFi Web API
            final ResourceCollection resources = new ResourceCollection(codeDocsResource, userGuideDocsResource);
            // Create the context handler
            final ServletContextHandler handler = new ServletContextHandler();
            FilterHolder frameOptions = new FilterHolder(FRAME_OPTIONS_FILTER);
            // <!-- This is the filter that does not get called when a request is made to localhost:8181/all-docs -->
            handler.addFilter(frameOptions, "/*", EnumSet.allOf(DispatcherType.class));
            System.out.println("Loading documents web app with context path set to " + contextPath);
            return handler;
        } catch (Exception ex) {
            System.out.println("Unhandled Exception in createDocsWebApp: " + ex.getMessage());
            return null;    // required by compiler, though never be executed.
    private static final Filter FRAME_OPTIONS_FILTER = new Filter() {
        private static final String FRAME_OPTIONS = "X-Frame-Options";
        private static final String SAME_ORIGIN = "SAMEORIGIN";
        public void doFilter(final ServletRequest req, final ServletResponse resp, final FilterChain filterChain)
                throws IOException, ServletException {
            // set frame options accordingly
            final HttpServletResponse response = (HttpServletResponse) resp;
            response.setHeader(FRAME_OPTIONS, SAME_ORIGIN);
            filterChain.doFilter(req, resp);
        public void init(final FilterConfig config) {
        public void destroy() {

In this case, when hitting localhost:8181/all-docs, the ResourceHandler returns the static resources but does not apply the X-Frame-Options header using the FRAME_OPTIONS_FILTER. How do I get this target to hit the Filter before handling the static resource request?

Thanks in advance.

On Fri, Jun 8, 2018 at 9:09 AM, Nathan Gough <returntosender404@xxxxxxxxx> wrote:

This Jetty doco page shows how to set up two context handlers which serve two different resource bases (eg. /var/www/docs and /var/www/api-docs) to the same path (eg.

A previous question showed how to do this with a ServletContextHandler: Serving static files from alternate path in embedded Jetty. You can add a Filter to a ServletContextHandler, but how do you add a Filter to a ContextHandlerCollection? For example an X-Frame-Options header? Is there a way to do split file/multiple resource bases for the same target and also add a header using an embedded method?


jetty-dev mailing list
To change your delivery options, retrieve your password, or unsubscribe from this list, visit

Back to the top