我试图用spring-boot支撑嵌入式Tomcat。我想在应用程序中将CXF用于一组Web服务,但是我不知道如何站立CXF Servlet。
我的主班看起来像这样…
@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; } }
我的CfxInitializer就像这样…
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/*"); } }
当我尝试使用典型命令构建和启动jar时 ./gradlew build && java -jar build/libs/gs-spring- boot-0.1.0.jar
./gradlew build && java -jar build/libs/gs-spring- boot-0.1.0.jar
我收到多个上下文的异常。
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)
这是一个更完整的pastebin- http: //pastebin.com/bcJ2ULhM
与Dave的答案类似,我可以通过删除ServletContextInitializer并将一个bean添加到Application Class来修复它。
@Bean public ServletRegistrationBean servletRegistrationBean(){ return new ServletRegistrationBean(new CXFServlet(),"/api/*"); }
Spring Boot嵌入式Servlet功能旨在与Servlet和一起使用ServletRegistration @Beans,而不是与一起使用ContextLoaderListener(这似乎是它试图窃取ServletContext根上下文的属性)。尝试ServletRegistration为您的servlet 添加一个;如果它是Spring感知的,并且假设它具有一个接口可以让您更改应用程序上下文或上下文位置,那么您应该能够在注册中对其进行配置。
Servlet
ServletRegistration
@Beans
ContextLoaderListener
ServletContext