Как динамически добавлять сервлеты на сервер причала?

Я создаю сервер причала и хочу программно и динамически добавлять сервлеты.

Я настраиваю ведение журнала и консоль, а затем приступаю к созданию сервера следующим образом:

Connector               httpConn        = null;
Connector               httpsConn       = null;
HandlerCollection       handlers        = new HandlerCollection();
httpConn = new SelectChannelConnector();
httpConn.setPort( httpPort );
httpConn.setName( "HTTPConnector" );  // simillar setup for httpsConn if needed

contextHandlers = new ContextHandlerCollection();
if( launchServlets ) {
    // this is more or less the same servlet creation code as below but for launching
    // static servlets (in this example, there are none)
    holders = initializeServlets( configFilePath );
}
handlers.addHandler( contextHandlers );

server = new Server();
if( httpConn != null ) {
    server.addConnector( httpConn );
}
if( httpsConn != null ) {
    server.addConnector( httpsConn );
}

server.setGracefulShutdown( 1000 ); /
server.setStopAtShutdown( true );
server.setHandler( handlers );
server.start();

if( launchServlets ) {
    // Catch any exception that occurs during servlet init()
    // (must be called after server.start() )
    for( int i = 0; i < holders.length; i++ ) {
        if( holders[ i ] != null ) {
            Exception initEx = holders[ i ].getUnavailableException();
            if( initEx != null ) {
                server.stop();
                throw initEx;
            }
        }
    }
}

Поэтому, когда мне нужно запустить сервлет, я делаю следующее:

boolean isSecureOnly = false;  // function that decides suppressed for now
String[] connectors;

MyServlet myServlet = new MyServlet();

ServletHolder holder = new ServletHolder( myServlet );
holder.setInitParameter( Constants.CONF_INIT_STRING_PARAM, configString );
holder.setInitParameter( Constants.CONF_INIT_NAME_PARAM, myName );
ServletContextHandler handler = new ServletContextHandler();
if( details != null ) {
    details.sch = handler;
}
String contextPath = MyConfig.getContextPath( myProps, myName );
handler.setContextPath( contextPath );
handler.setAllowNullPathInfo( true );

// bind the servlet to the connectors it should be listening to
if( isSsl ) {
    if( isSecureOnly ) {
        connectors = new String[ 1 ];
        connectors[0] = Constants.CONF_HTTPS_CONNECTOR;
    } else {
        connectors = new String[ 2 ];
        connectors[0] = Constants.CONF_HTTPS_CONNECTOR;
        connectors[1] = Constants.CONF_HTTP_CONNECTOR;
    }
} else {
    if( isSecureOnly ) {
    throw new ConfigException( 50051 );
    }
    connectors = new String[ 1 ];
    connectors[0] = Constants.CONF_HTTP_CONNECTOR;
}
handler.setConnectorNames( connectors );

if( myName != null ) {
    handler.setDisplayName( MyMessage.message( 10025, myName ) );
} else {
    handler.setDisplayName( MyMessage.message( 10001 ) );
}
handler.addServlet( holder, "/*" );
contextHandlers.addHandler( handler );

contextHandlers.mapContexts();
Exception initEx = holder.getUnavailableException();
if( initEx != null ) {
    // deal with error
}

Хотя мой код запуска динамического сервлета работает без ошибок, консоль не показывает инициализацию сервлета. Когда у меня есть launchServlets=true, код будет запускать сервлеты статически, и все в порядке, но я хочу запускать их динамически.

Должен ли я вручную инициализировать сервлет (я думал, что сервлеты изолированы в своем собственном пространстве памяти)? Как сказать Jetty запустить новый сервлет?

Обновление: до сих пор мне удалось запустить сервлет только с помощью server.stop()/server.join()/server.start(). Я хотел бы добавить сервлеты (и удалить - но это дополнительный вопрос), чтобы не прерывать обслуживание существующих сервлетов)?

Я использую jetty-all-server-8.1.3 и API сервлета 3.0.

Заранее спасибо за помощь/подсказки!


person Philippe Bertrand    schedule 12.09.2014    source источник
comment
Надгробие! Действительно! Я почти уверен, что большинство просмотров были моими! Люди с вводными вопросами по CS получают здесь больше голосов.   -  person Philippe Bertrand    schedule 17.11.2014


Ответы (1)


Я не уверен, что это безопасный способ сделать это, но я запустил сервлет, вызвав start() в ServletContextHandler() вместо того, чтобы останавливать и запускать сервер.

Это работало как для 8.1.3, так и для 9.2.4 (которую я обновил вместе с обновлением API сервлета до 3.1)

Надеюсь, это поможет кому-то еще, кто заинтересован в том, чтобы сделать что-то подобное.

person Philippe Bertrand    schedule 17.11.2014