Reputation: 31
I am trying to implement cors in a embedded jetty server. I feel lost right now with this exception.
java.lang.IllegalStateException: No filter named cross-origin
at org.eclipse.jetty.servlet.ServletHandler.updateMappings(ServletHandler.java:1260)
at org.eclipse.jetty.servlet.ServletHandler.doStart(ServletHandler.java:179)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:171)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:89)
at org.eclipse.jetty.server.handler.ScopedHandler.doStart(ScopedHandler.java:112)
at org.eclipse.jetty.server.session.SessionHandler.doStart(SessionHandler.java:486)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:171)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:89)
at org.eclipse.jetty.server.handler.ScopedHandler.doStart(ScopedHandler.java:112)
at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:955)
at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:388)
at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:896)
at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:306)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:171)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:121)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:89)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:171)
at org.eclipse.jetty.server.Server.start(Server.java:469)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:89)
at org.eclipse.jetty.server.Server.doStart(Server.java:414)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
at org.projectsanatan.restsanatan.RestSanatan.start(RestSanatan.java:38)
at org.projectsanatan.restsanatan.Main.main(Main.java:16)
My code is
private void initServlets() {
ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
servletContextHandler.setContextPath("/");
ResourceConfig resourceCfg = new ResourceConfig();
resourceCfg.packages(BookResource.class.getPackage().getName(), "/*");
ServletContainer servletContainer = new ServletContainer(resourceCfg);
ServletHolder servletHolder = new ServletHolder(servletContainer);
servletContextHandler.addServlet(servletHolder, "/api/*");
// servletContextHandler.addFilter(null, KEY, null)
FilterHolder corsFilter = new FilterHolder();
corsFilter.setInitParameter("allowedOrigins", "https://example.com");
corsFilter.setInitParameter("allowedMethods", "POST,GET,OPTIONS,PUT,DELETE,HEAD");
corsFilter.setInitParameter("allowedHeaders", "X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept");
corsFilter.setInitParameter("preflightMaxAge", "728000");
corsFilter.setInitParameter("allowCredentials", "true");
corsFilter.setInitParameter("chainPreflight", "false");
CrossOriginFilter cors = new CrossOriginFilter();
corsFilter.setFilter(cors);
FilterMapping corsFilterMap = new FilterMapping();
corsFilterMap.setFilterName("cross-origin");
corsFilterMap.setPathSpec("/*");
corsFilterMap.setDispatcherTypes(EnumSet.of(DispatcherType.INCLUDE, DispatcherType.REQUEST));
servletContextHandler.getServletHandler().addFilter(corsFilter, corsFilterMap);
this.handlerList.addHandler(servletContextHandler);
this.setHandler(this.handlerList);
}
I am not very much experienced with jetty and servlet stuff so I am confused, help would be really appreciated!
Upvotes: 2
Views: 838
Reputation: 49462
There's a few issues.
ServletContextHandler
, not the ServletHandler
.FilterHolder
+ Mapping with name, then you have to name your FilterHolder
.WEB-INF/web.xml
based configuration. Just use the FilterHolder
directly.ServletContextHandler
BaseResource declarationDefaultServlet
on your ServletContext
DefaultHandler
on your top level handler tree (usually set as last entry)A correct setup would be like this ...
ServletContextHandler servletContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
servletContextHandler.setContextPath("/");
// Base Resource is required for your setup
servletContextHandler.setBaseResource(Resource.newResource(urlToStaticContent));
ResourceConfig resourceCfg = new ResourceConfig();
resourceCfg.packages(BookResource.class.getPackage().getName(), "/*");
ServletContainer servletContainer = new ServletContainer(resourceCfg);
ServletHolder servletHolder = new ServletHolder(servletContainer);
servletContextHandler.addServlet(servletHolder, "/api/*");
FilterHolder corsHolder = servletContextHandler.addFilter(CrossOriginFilter.class,
"/*",
EnumSet.of(DispatcherType.INCLUDE, DispatcherType.REQUEST));
corsHolder.setInitParameter("allowedOrigins", "https://example.com");
corsHolder.setInitParameter("allowedMethods", "POST,GET,OPTIONS,PUT,DELETE,HEAD");
corsHolder.setInitParameter("allowedHeaders", "X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept");
corsHolder.setInitParameter("preflightMaxAge", "728000");
corsHolder.setInitParameter("allowCredentials", "true");
corsHolder.setInitParameter("chainPreflight", "false");
// Default Servlet is Required
ServletHolder defaultHolder = new ServletHolder("default", DefaultServlet.class);
servletContextHandler.addServlet(defaultHolder, "/"); // default url-pattern
HandlerList handlerList = new HandlerList();
handlerList.addHandler(servletContextHandler);
// Default Handler is for requests that don't match a context above
// Such as requests that don't have a path that start with "/"
// It is safe to leave active, even in production, and will help with troubleshooting issues
handlerList.addHandler(new DefaultHandler());
server.setHandler(handlerList);
The Filter mapping of your CrossOriginFilter
has specified the DispatcherType
set of INCLUDE
and REQUEST
, that's a really odd setup.
Doing CORS from an INCLUDE
(or FORWARD
) dispatch is super awkward, skip it.
But you didn't specify ASYNC
, which is actually super common.
I would change the mapping this way ...
FilterHolder corsHolder = servletContextHandler.addFilter(CrossOriginFilter.class,
"/*",
EnumSet.of(DispatcherType.REQUEST, DispatcherType.ASYNC));
Things to keep in mind for using CrossOriginFilter
.
Origin
request header will not trigger the CrossOriginFilter
.Upvotes: 1