【问题标题】:embedded jetty CrossDomainFilter not working嵌入式码头CrossDomainFilter不工作
【发布时间】: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);

同样的结果,我从来没有看到跨域标头。我还需要做什么才能使此过滤器正常工作?

【问题讨论】:

    标签: java jetty cors embedded-jetty


    【解决方案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:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-25
    • 2019-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多