Stivaletto a molla con Tomcat e CXF-servlet
-
20-12-2019 - |
Domanda
Sto cercando di alzare un tomcat incorporato con boot a molla.Voglio usare CXF per un set di servizi Web nell'app ma non posso capire come contrastare il servlet CXF.
La mia classe principale sembra questa ...
@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackages={"com.connecture.services.documentservice.webservice"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(new Class[] { Application.class, CfxInitializer.class }, args);
}
@Bean
public EmbeddedServletContainerFactory embeddedServletContainerFactory() {
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory("", 8080);
return factory;
}
}
.
E il mio cfxinitilizzatore come questo ...
public class CfxInitializer implements ServletContextInitializer
{
@Override
public void onStartup(ServletContext servletContext) throws ServletException
{
XmlWebApplicationContext rootContext = new XmlWebApplicationContext();
rootContext.setConfigLocations(new String[] { "classpath*:applicationContext.xml" });
servletContext.addListener(new ContextLoaderListener(rootContext));
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("CXFServlet", CXFServlet.class);
dispatcher.addMapping("/api/*");
}
}
.
Quando provo a costruire e avviare il barattolo con il tipico comando ./gradlew build && java -jar build/libs/gs-spring-boot-0.1.0.jar
Ottengo un'eccezione per più contesti.
Java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:277)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4971)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
.
Ecco una pastebina più completa - http://pastebin.com/bcj2ulhm
------------------------------------------------------------------------------------
Allo stesso modo alla risposta di Dave sono stato in grado di risolverlo rimuovendo il ServletContextinizializzatore e aggiungendo un fagiolo alla classe di applicazione.
@Bean
public ServletRegistrationBean servletRegistrationBean(){
return new ServletRegistrationBean(new CXFServlet(),"/api/*");
}
. Soluzione
Le funzioni del servlet incorporato della molla sono progettate per funzionare con Servlet
e ServletRegistration
@Beans
Gode e non con il ContextLoaderListener
(che sembra che stia cercando di rubare l'attributo ServletContext
per il contesto della root).Prova ad aggiungere un ServletRegistration
per il servlet invece;Se è a molla consapevole, supponendo che abbia un'interfaccia che consente di modificare il contesto dell'applicazione o la posizione del contesto, è possibile configurarlo nella registrazione.
Altri suggerimenti
Ho trovato il seguente progetto su GitHub che mi ha aiutato a iniziare
I campioni ora fanno parte del wiki CXF: http://cxf.apache.org/docs/jaxrs-services-configuration.html#jaxrsservicesconfiguration-springboot