首页 文章

嵌入式Jetty - 启动Jetty Server后添加上下文

提问于
浏览
1

是否正确启动没有指定上下文且没有上下文处理程序的jetty实例,然后在服务器启动后继续向其添加上下文 . 虽然我能够使用可变的HandlerCollection执行此操作,并且日志显示服务器和上下文已启动且可用,但我无法使用URL访问它 . 或者我们应该在启动时向服务器添加至少一个根上下文和上下文处理程序吗?

我做了类似于下面链接中建议的示例 . Jetty 9 (embedded): Adding handlers during runtime

我的码头版本是9.3.7.v20160115

1 回答

  • 3

    向正在运行的服务器添加处理程序是一种常见的模式,但文档根本不清楚("embedding jetty"教程中的所有示例都启动服务器 after 配置 . )AFAIK人员遵循以下方法:

    1)使用HandlerCollection(boolean mutableWhenRunning)ctor添加/删除处理程序

    2)显式添加和启动处理程序

    我观察到Jetty 9.1.4中不需要#2,但它在Jetty 9.2.14及之后(BTW这些版本号被Maven挑选为泽西依赖,这与此问题完全无关 . )例如:

    // after server creation ...
        ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection();
                jettyServer.setHandler(contextHandlerCollection);
        jettyServer.start();
        // ...
        ServletContextHandler newSCH= new ServletContextHandler(ServletContextHandler.SESSIONS);
            newSCH.setResourceBase(System.getProperty("java.io.tmpdir"));
            newSCH.setContextPath("/servlets");
            ServletHolder newHolder = new SwServletHolder(servlet);
            newSCH.addServlet(newHolder, "/*");
            contextHandlerCollection.addHandler(newSCH);
            try {
                    newSCH.start(); // needed from about 9.2
            } catch (Exception e) {
                    logger.info("Exception starting ServletContextHandler for Jetty", e);
            }
    

    为了添加SOAP上下文,这是一个“习惯于在9.1.4工作”的代码(9.2.14报告404):

    import java.lang.reflect.Method;
    import java.net.InetSocketAddress;
    
    import javax.jws.WebService;
    import javax.xml.ws.Endpoint;
    
    import org.eclipse.jetty.http.spi.JettyHttpServerProvider;
    import org.eclipse.jetty.http.spi.HttpSpiContextHandler;
    import org.eclipse.jetty.http.spi.JettyHttpContext;
    import org.eclipse.jetty.http.spi.JettyHttpServer;
    import org.eclipse.jetty.server.Server;
    import org.eclipse.jetty.server.handler.ContextHandlerCollection;
    
    import com.sun.net.httpserver.HttpContext;
    
    public class JettyJaxWs {
    
        public static void main(String[] args) throws Exception {
            Server server = new Server(7777);
            ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection();
            server.setHandler(contextHandlerCollection);
            server.start();
            HttpContext context = buildOrig(server, "/ws");
            MyWebService ws = new MyWebService();
            Endpoint endpoint = Endpoint.create(ws);
            endpoint.publish(context);
            // access wsdl on http://localhost:7777/ws/MyWebService?wsdl
        }
    
        @WebService
        public static class MyWebService {
    
            public String hello(String s) {
                return "hi " + s;
            }
        }
    
        public static HttpContext buildOrig(Server server, String contextString) throws Exception {
            JettyHttpServerProvider.setServer(server);
            return new JettyHttpServerProvider().createHttpServer(new InetSocketAddress(7777), 5).createContext(contextString);
        }
    

    后来,我不得不为最后一个方法做这个(不确定是否有更好的方法):

    public static HttpContext buildNew(Server server, String contextString) {
            JettyHttpServer jettyHttpServer = new JettyHttpServer(server, true);
            JettyHttpContext ctx = (JettyHttpContext) jettyHttpServer.createContext(contextString);
            try {
                Method method = JettyHttpContext.class.getDeclaredMethod("getJettyContextHandler");
                method.setAccessible(true);
                HttpSpiContextHandler contextHandler = (HttpSpiContextHandler) method.invoke(ctx);
                contextHandler.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return ctx;
        }
    

相关问题