Может ли какой-нибудь код выполняться при первом развертывании файла WAR? - PullRequest
7 голосов
/ 17 марта 2011

Существует ли какой-либо метод или API, который я могу использовать, чтобы при каждом развертывании нового файла WAR выполнялась часть кода или, возможно, при запуске Tomcat соответствующий сервлет запускался или выполнял некоторый код непрерывно.

Ответы [ 3 ]

10 голосов
/ 22 мая 2013

Восстановление старого вопроса, поскольку единственный ответ не показывает ни одного примера.

Для запуска пользовательского фрагмента кода при развертывании / отмене развертывания WAR веб-приложения или запуске / остановке Tomcat необходимо:

  1. Реализация слушателя ServletContextListener и его методов contextInitialized() и contextDestroyed().
  2. Сообщите Tomcat о вашей реализации. Согласно документации , вы можете добавить реализующий класс в дескриптор развертывания, добавить к нему аннотацию WebListener или зарегистрировать его одним из методов addListener(), определенных в ServletContext.

Вот пример (на основе этого поста ):

package com.example;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyServletContextListener implements ServletContextListener {
    /** The servlet context with which we are associated. */
    private ServletContext context = null;

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        log("Context destroyed");
        this.context = null;
    }

    @Override
    public void contextInitialized(ServletContextEvent event) {
        this.context = event.getServletContext();
        log("Context initialized");
    }

    private void log(String message) {
        if (context != null) {
            context.log("MyServletContextListener: " + message);
        } else {
            System.out.println("MyServletContextListener: " + message);
        }
    }
}

И добавить следующее к web.xml (или, альтернативно, использовать аннотацию WebListener или метод addListener()):

<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    ...
    <listener>
        <listener-class>com.example.MyServletContextListener</listener-class>
    </listener>
</web-app>
6 голосов
/ 17 марта 2011

Вы можете включить «ContextListener» в web.xml.Экземпляр этого класса будет создан, когда WARB приложения Webb собирается развернуть / запустить.

Этот код может запустить поток, который будет продолжать работать до развертывания приложения.

Пример: http://www.javafaq.nu/java-example-code-233.html

0 голосов
/ 24 февраля 2017

Я нахожу способ запустить некоторый код только при развертывании приложения (* .war): это работает по крайней мере для сервлетов jersey с сервлетом java, использующих javax.ws.rs.core.Application.

Приложение в файле ApplicationConfig.java (см. Ниже) содержит метод public getClasses, который вызывается при развертывании приложения. Таким образом, добавление кода в getClasses приводит к его выполнению при развертывании приложения. Единственное замечание, которое я заметил, это то, что странно эта функция вызывается дважды, не знаю почему, поэтому я добавил глобальную переменную в класс ApplicationConfig, чтобы узнать, выполнялся ли мой код.

Вот мое решение:

package eu.oca;

import java.util.Set;
import javax.ws.rs.core.Application;

/**                                                                                                                             
 *                                                                                                                              
 * @author mattei                                                                                                               
 */
@javax.ws.rs.ApplicationPath("jersey")
public class ApplicationConfig extends Application {

    private boolean alreadyRun = false;

    @Override
    public Set<Class<?>> getClasses() {

        System.out.println("Sidonie : ApplicationConfig : getClasses : alreadyRun = " + String.valueOf(alreadyRun));
        alreadyRun = true;
        Set<Class<?>> resources = new java.util.HashSet<>();
        addRestResourceClasses(resources);
        return resources;
    }

    /**                                                                                                                         
     * Do not modify addRestResourceClasses() method.                                                                           
     * It is automatically populated with                                                                                       
     * all resources defined in the project.                                                                                    
     * If required, comment out calling this method in getClasses().                                                            
     */
    private void addRestResourceClasses(Set<Class<?>> resources) {
        resources.add(eu.oca.ResultatGeneralAF.class);
        resources.add(eu.oca.ResultatGeneralF.class);
        resources.add(eu.oca.ResultatMesuresAF.class);
        resources.add(eu.oca.ResultatMesuresF.class);
        resources.add(eu.oca.SidonieAccueilD.class);
        resources.add(eu.oca.SidonieWelcomeR.class);
    }

}
...