我们首次部署WAR文件时是否可以运行某些代码?

时间:2011-03-17 07:46:40

标签: tomcat web-deployment

我是否可以使用任何方法或API,以便每当我部署新的WAR文件时,应该执行一部分代码,或者当Tomcat启动时,相应的servlet应该连续启动或运行某些代码。

3 个答案:

答案 0 :(得分:10)

恢复一个旧问题,因为唯一的答案没有显示任何例子。

为了在部署/取消部署Web应用程序WAR或启动/停止Tomcat时运行自定义代码段,您需要:

  1. 实施ServletContextListener侦听器及其方法contextInitialized()contextDestroyed()
  2. 让Tomcat了解您的实施情况。根据{{​​3}},您可以将实现类添加到部署描述符,使用WebListener对其进行注释,或者通过addListener()上定义的ServletContext方法之一注册它
  3. 以下是一个示例(基于documentation):

    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>
    

答案 1 :(得分:6)

您可以在web.xml中包含“ContextListener”。当即将部署/启动Webb应用程序WAR时,将创建此类的实例。

此代码可以启动一个可以继续运行的线程,直到部署应用程序。

示例:http://www.javafaq.nu/java-example-code-233.html

答案 2 :(得分:0)

我找到了一种只在应用程序(* .war)部署时运行某些代码的方法: 它至少适用于使用javax.ws.rs.core.Application的java servlet的jersey servlet。

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);
    }

}