springboot mit Tomcat und CXF-Servlet
-
20-12-2019 - |
Frage
Ich versuche, einen eingebetteten Kater mit Spring-Boot aufzustehen.Ich möchte CXF für eine Reihe von Webdiensten in der App verwenden, kann aber nicht herausfinden, wie ich das CXF-Servlet aufstellen soll.
Meine Hauptklasse sieht so aus...
@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;
}
}
Und mein CfxInitializer so...
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/*");
}
}
Wenn ich versuche, das Glas mit dem typischen Befehl zu erstellen und zu starten ./gradlew build && java -jar build/libs/gs-spring-boot-0.1.0.jar
Ich bekomme eine Ausnahme für mehrere Kontexte.
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)
Hier ist ein vollständigerer Pastebin - http://pastebin.com/bcJ2ULhM
----------------------------------------------------------------------------------
Ähnlich wie bei Daves Antwort konnte ich das Problem beheben, indem ich den ServletContextInitializer entfernte und der Anwendungsklasse eine Bean hinzufügte.
@Bean
public ServletRegistrationBean servletRegistrationBean(){
return new ServletRegistrationBean(new CXFServlet(),"/api/*");
}
Lösung
Die eingebetteten Servlet-Funktionen von Spring Boot sind für die Arbeit mit konzipiert Servlet
und ServletRegistration
@Beans
, und nicht mit dem ContextLoaderListener
(was aussieht, als würde es versuchen, das zu stehlen) ServletContext
attribut für den Root-Kontext).Versuchen Sie, ein hinzuzufügen ServletRegistration
stattdessen für Ihr Servlet;wenn es Spring-fähig ist, vorausgesetzt, es verfügt über eine Schnittstelle, mit der Sie den Anwendungskontext oder den Kontextspeicherort ändern können, sollten Sie es in der Registrierung konfigurieren können.
Andere Tipps
Ich habe das folgende Projekt auf Github gefunden, das mir beim Einstieg geholfen hat
https://github.com/ungerts/spring-boot-jaxrs-sample
Arbeitete für mich mit:
- frühling-boot 1.2.3
- cxf-rt-frontend-jaxrs:3.1.0
- jackson-jaxrs-json-Anbieter:2.5.3
Beispiele sind jetzt Teil des CXF-Wikis: http://cxf.apache.org/docs/jaxrs-services-configuration.html#JAXRSServicesConfiguration-SpringBoot