嵌入式码头CrossDomainFilter不工作
Posted
技术标签:
【中文标题】嵌入式码头CrossDomainFilter不工作【英文标题】:embedded jetty CrossDomainFilter not working 【发布时间】:2015-07-11 03:12:03 【问题描述】:我找不到使用我的处理程序和过滤器组合的嵌入式码头的示例。由于某种原因,我无法确定我没有得到 CORS 标头。这是我目前的来源:
private static Server setupJetty(Properties prop)
Server server = new Server(Integer.parseInt(prop.getProperty("port")));
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath(prop.getProperty("contextpath"));
ContextHandlerCollection contexts = new ContextHandlerCollection();
RequestLogHandler requestLogHandler= setupLogging(server, prop.getProperty("logslocn"));
ServletHolder jerseyServlet = context.addServlet(ServletContainer.class, "/*");
jerseyServlet.setInitOrder(0);
// Tells the Jersey Servlet which REST service/class to load.
jerseyServlet.setInitParameter(ServerProperties.PROVIDER_PACKAGES, "org.example.pss.resources");
context.addServlet(jerseyServlet, prop.getProperty("servletpath"));
ServletHandler handler = new ServletHandler();
handler.addServletWithMapping(jerseyServlet, "/*");
FilterHolder filterHolder = new FilterHolder(new CrossOriginFilter());
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*"); // allowed origins comma separated
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "Content-Type,Authorization,X-Requested-With,Content-Length,Accept,Origin");
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,PUT,POST,DELETE,OPTIONS");
filterHolder.setInitParameter(CrossOriginFilter.PREFLIGHT_MAX_AGE_PARAM, "5184000"); // 2 months
filterHolder.setInitParameter(CrossOriginFilter.ALLOW_CREDENTIALS_PARAM, "true");
filterHolder.setName("cross-origin");
FilterMapping fm = new FilterMapping();
fm.setFilterName("cross-origin");
fm.setPathSpec("*");
handler.addFilter(filterHolder,fm);
HandlerCollection handlers = new HandlerCollection();
handlers.setHandlers(new Handler[]context, handler, contexts,
new DefaultHandler(), requestLogHandler);
server.setHandler(handlers);
return server;
我也试过了:
FilterHolder filterHolder = new FilterHolder(new CrossOriginFilter());
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "/*"); // allowed origins comma separated
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "Content-Type,Authorization,X-Requested-With,Content-Length,Accept,Origin");
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,PUT,POST,DELETE,OPTIONS");
filterHolder.setInitParameter(CrossOriginFilter.PREFLIGHT_MAX_AGE_PARAM, "5184000"); // 2 months
filterHolder.setInitParameter(CrossOriginFilter.ALLOW_CREDENTIALS_PARAM, "true");
context.addFilter(filterHolder,"/*",EnumSet.allOf(DispatcherType.class));
HandlerCollection handlers = new HandlerCollection();
handlers.setHandlers(new Handler[]context, contexts,
new DefaultHandler(), requestLogHandler);
server.setHandler(handlers);
同样的结果,我从来没有看到跨域标头。我还需要做什么才能使此过滤器正常工作?
【问题讨论】:
【参考方案1】:不要直接使用ServletHandler
,那是一个内部类。
过滤器始终是ServletContextHandler
(或更专业的WebAppContext
)的一部分
您的配置在 /*
上下文路径中添加了 2 个 servlet(这是不行的)
您的配置在DefaultHandler
之后添加您的RequestLogHandler
(这意味着RequestLogHandler
永远不会运行)
DefaultHandler
应该在主处理程序列表的末尾
DefaultServlet
需要存在于您的ServletContextHandler
中
您的ServletContextHandler
缺少必需的resourceBase
(这是指向有效位置的路径或URL,以使ServletContext
可以正常查找资源)
*
的路径规范无效。 (请记住,您可以使用前缀/a/b/*
、后缀*.foo
、精确/a/b/c
或默认/
)
所以,为了简化...
package org.eclipse.jetty.demo;
import java.util.EnumSet;
import javax.servlet.DispatcherType;
import org.eclipse.jetty.server.AsyncNCSARequestLog;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.RequestLogHandler;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.servlets.CrossOriginFilter;
import org.glassfish.jersey.server.ServerProperties;
import org.glassfish.jersey.servlet.ServletContainer;
public class JerseyWithCors
public static void main(String[] args)
try
new JerseyWithCors().exec();
catch (Throwable t)
t.printStackTrace(System.err);
public void exec() throws Exception
int port = 8080;
Server server = new Server(port);
HandlerList handlers = new HandlerList();
server.setHandler(handlers);
handlers.addHandler(getAccessLogHandler());
handlers.addHandler(getMainServletContext());
// DefaultHandler is always last for the main handler tree
// It's responsible for Error handling of all prior handlers.
// It will always respond (if the request reaches this far)
handlers.addHandler(new DefaultHandler());
server.start();
server.join();
public Handler getAccessLogHandler()
RequestLogHandler logHandler = new RequestLogHandler();
AsyncNCSARequestLog log = new AsyncNCSARequestLog();
log.setFilename("logs/access-yyyy_mm_dd.log");
logHandler.setRequestLog(log);
return logHandler;
public Handler getMainServletContext()
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
// always need a resource base
context.setResourceBase("path/to/webroot");
ServletHolder jerseyServlet = context.addServlet(ServletContainer.class,"/*");
jerseyServlet.setInitOrder(0);
jerseyServlet.setInitParameter(ServerProperties.PROVIDER_PACKAGES,"org.example.pss.resources");
FilterHolder filterHolder = context.addFilter(CrossOriginFilter.class,"/*",EnumSet.allOf(DispatcherType.class));
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM,"*");
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM,"Content-Type,Authorization,X-Requested-With,Content-Length,Accept,Origin");
filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM,"GET,PUT,POST,DELETE,OPTIONS");
filterHolder.setInitParameter(CrossOriginFilter.PREFLIGHT_MAX_AGE_PARAM,"5184000");
filterHolder.setInitParameter(CrossOriginFilter.ALLOW_CREDENTIALS_PARAM,"true");
// DefaultServlet is always last for a ServletContext
context.addServlet(DefaultServlet.class,"/");
return context;
【讨论】:
谢谢乔金。像这样的示例将增强 Jetty 的文档,嵌入式设置没有涵盖 webapp 操作和静态配置文件。 我仍然没有得到 CORS 标头?我添加了: filterHolder.setInitParameter(CrossOriginFilter.EXPOSED_HEADERS_PARAM,("Access-Control-Allow-Origin"));还是不明白。所以目前还没有跨域支持。我怎么得到这个?我 GET 带有标题:主机:pss.hcl.com:8088 用户代理:Mozilla/5.0 (Windows NT 6.3; WOW64; rv:37.0) Gecko/20100101 Firefox/37.0 接受:text/html,application/xhtml+xml, application/xml;q=0.9,/;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Get:以上是关于嵌入式码头CrossDomainFilter不工作的主要内容,如果未能解决你的问题,请参考以下文章
为啥有人会使用 jetty-maven-plugin 与嵌入式码头
如何让 WebApp 在嵌入式码头的类路径上找到应用程序属性?