[英]Embedded Jetty no filter named cross-origin
I am trying to implement cors in a embedded jetty server.我正在尝试在嵌入式码头服务器中实现 cors。 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!我对码头和 servlet 的东西不是很有经验,所以我很困惑,非常感谢帮助!
There's a few issues.有几个问题。
ServletContextHandler
, not the ServletHandler
. ServletContextHandler
完成的,而不是ServletHandler
。FilterHolder
+ Mapping with name, then you have to name your FilterHolder
.FilterHolder
+ Mapping,则必须命名您的FilterHolder
。WEB-INF/web.xml
based configuration.WEB-INF/web.xml
的配置中。 Just use the FilterHolder
directly.FilterHolder
即可。ServletContextHandler
BaseResource declarationServletContextHandler
BaseResource 声明DefaultServlet
on your ServletContext
ServletContext
上缺少所需的DefaultServlet
DefaultHandler
on your top level handler tree (usually set as last entry)DefaultHandler
(通常设置为最后一个条目) 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.您的
CrossOriginFilter
的 Filter 映射指定了INCLUDE
和REQUEST
的DispatcherType
集,这是一个非常奇怪的设置。
Doing CORS from an INCLUDE
(or FORWARD
) dispatch is super awkward, skip it.从
INCLUDE
(或FORWARD
)调度执行 CORS 非常尴尬,跳过它。
But you didn't specify ASYNC
, which is actually super common.但是您没有指定
ASYNC
,这实际上非常常见。
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
.使用
CrossOriginFilter
的注意事项。
Origin
request header will not trigger the CrossOriginFilter
.Origin
请求 header 的请求不会触发CrossOriginFilter
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.