Jetty How to add a servlet to multiple ServletCont

2019-08-27 06:27发布

问题:

I need to intercept all the requests when there are multiple ServletContextHandler configured.

I have multiple ServletContextHandler in a ContextHandlerCollection and a ContainerRequestFilter. I need this ContainerRequestFilter to be added to all ServletContextHandler Only way I could find of adding the ContainerRequestFilter was through ResourceConfig. So I did this:

ResourceConfig resourceConfig = new ResourceConfig();
resourceConfig.register(MyContainerRequestFilter.class);
ServletHolder s = new ServletHolder(new ServletContainer(resourceConfig));
for (Handler context : contextHandlers) {
    ((ServletContextHandler)context).addServlet(s, "/*");
} 

which results in:

java.lang.IllegalStateException: Multiple servlets map to path: /*: org.eclipse.jetty.proxy.ProxyServlet$Transparent-56c0a61e

What is the right way to do this?

I also looked into handlers and tried following but it overrides all the other servlets contained in ContextHandlerCollection i.e., when I call /api (exists in one of the ServletContextHandler in ContextHandlerCollection), I get 404 because of context.setContextPath("/"); below, but then this request filter needs to be applied on base path anyway.

HandlerWrapper wrapper = new HandlerWrapper();
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
ResourceConfig resourceConfig = new ResourceConfig();
resourceConfig.register(RequestInterceptor.class);
context.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/*");
wrapper.setHandler(context)
HandlerCollection handlers = new HandlerCollection(true);
handlers.setHandlers(new Handler[]{wrapper,contexts});

I also tried adding filter to above collection:

HandlerWrapper wrapper = new HandlerWrapper();
FilterHolder filter = new FilterHolder(MyContainerRequestFilter.class);  // had to implment filter interface
wrapper.addFilterWithMapping(filter, "/*", EnumSet.allOf(DispatcherType.class)) ;
HandlerCollection handlers = new HandlerCollection(true);
handlers.setHandlers(new Handler[]{contexts,wrapper});

In this case request does come to the filter but I get following exception:

Could not send response error 500: java.lang.IllegalStateException: Committed Committed before 404 null

回答1:

I could not do it with ContainerRequestFilter but I had to use javax.servlet.Filter

And the correct way to add a javax.servlet.Filter in my case (Multiple ServletContextHandler) is:

Handler[] contextHandlers = contexts.getHandlers();

for (Handler context : contextHandlers) {
        ((ServletContextHandler)context).addFilter(RequestInterceptor.class, "/*", 
EnumSet.allOf(DispatcherType.class));
}