2015-07-13 7 views
23

Il tomcat incorporato di Spring Boot è molto utile, sia per lo sviluppo che per l'implementazione.Spring Boot: come aggiungere altri file WAR al tomcat incorporato?

E se fosse necessario aggiungere un altro file WAR (di terze parti) (ad esempio, GeoServer)?

Forse il seguente è la procedura normale:

  1. Installare un normale server Tomcat.
  2. Costruire l'applicazione Spring Boot come file WAR e aggiungerla alla cartella webapps di Tomcat.
  3. Inoltre, aggiungere un altro file WAR (di terze parti) alla cartella webapps.

Ma sarebbe bello se fosse possibile la seguente configurazione.

  1. Costruire l'applicazione di avvio Spring come Jar autonomo, che include Tomcat incorporato.
  2. Distribuire l'applicazione di avvio Spring Jar.
  3. Aggiungere un altro file WAR (di terze parti) a una cartella riconosciuta da Tomcat incorporato.
  4. Serve sia il contenuto dell'applicazione di avvio Spring che i contenuti di un'altra WAR utilizzando il Tomcat incorporato.

Come può essere fatto?

UPDATE

Quando l'applicazione di avvio molla è realizzata in vaso grasso (= jar eseguibile), il codice nella risposta non è sufficiente. Quello rivisto è la seguente:

@Bean 
public EmbeddedServletContainerFactory servletContainerFactory() { 
    return new TomcatEmbeddedServletContainerFactory() { 

     @Override 
     protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
       Tomcat tomcat) { 
      try { 
       Context context = tomcat.addWebapp("/foo", "/path/to/foo.war"); 
       WebappLoader loader = 
        new WebappLoader(Thread.currentThread().getContextClassLoader()); 
       context.setLoader(loader); 
      } catch (ServletException ex) { 
       throw new IllegalStateException("Failed to add webapp", ex); 
      } 
      return super.getTomcatEmbeddedServletContainer(tomcat); 
     } 

    }; 
} 

Dal momento che i file jar in un barattolo di grasso non possono essere caricate dal classloader di sistema, un programma di caricamento classe genitore esplicito deve essere specificato. Altrimenti, la WAR aggiuntiva non può caricare i jar della libreria nel jar grasso dell'applicazione di avvio a molla che ha aggiunto WAR.

+0

Leggere le descrizioni dei tag. "embedded" non è "embedding"! – Olaf

+0

Attualmente sto cercando di fare lo stesso ([vedi qui] (http://stackoverflow.com/questions/42191815/cannot-add-web-application-to-built-in-tomcat)) ma sto ottenendo tonnellate di eccezioni a causa delle dipendenze dei file mancanti. Qualche idea di cosa mi sto perdendo qui? – displayname

risposta

19

È possibile aggiungere un file di guerra a Tomcat incorporato utilizzando Tomcat.addWebapp. Come dice la javadoc, è "l'equivalente di aggiungere un'applicazione web alla directory delle app Web di Tomcat". Per utilizzare questa API in Spring Boot, è necessario utilizzare una sottoclasse personalizzata TomcatEmbeddedServletContainerFactory:

@Bean 
public EmbeddedServletContainerFactory servletContainerFactory() { 
    return new TomcatEmbeddedServletContainerFactory() { 

     @Override 
     protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(
       Tomcat tomcat) { 
      // Ensure that the webapps directory exists 
      new File(tomcat.getServer().getCatalinaBase(), "webapps").mkdirs(); 

      try { 
       Context context = tomcat.addWebapp("/foo", "/path/to/foo.war"); 
       // Allow the webapp to load classes from your fat jar 
       context.setParentClassLoader(getClass().getClassLoader()); 
      } catch (ServletException ex) { 
       throw new IllegalStateException("Failed to add webapp", ex); 
      } 
      return super.getTomcatEmbeddedServletContainer(tomcat); 
     } 

    }; 
} 
+0

Grazie! Sono riuscito a integrare una WAR con il tuo codice. (Appaiono alcuni avvertimenti, ma è specifico per la GUERRA che ho aggiunto e immagino che possa essere risolto). – zeodtr

+6

Un piccolo problema: quando server.tomcat.basedir non è specificato in application.properties, l'espansione WAR fallisce. Il motivo è il seguente: Se tale variabile non viene specificata, Spring crea una directory temporanea e la assegna come baseDir. Ma quella directory non ha una sottodirectory 'wepapps' in cui il tomcat incorporato prova a mkdir() una sottodirectory per i file espansi di WAR. – zeodtr

+0

Quando l'applicazione di avvio a molla è fatta di vasetti di grasso, il codice sopra riportato non è sufficiente. Si prega di consultare il mio AGGIORNAMENTO. – zeodtr