【问题标题】:spring-boot with tomcat and cxf-servlet带有tomcat和cxf-servlet的spring-boot
【发布时间】:2014-07-23 00:24:22
【问题描述】:

我正在尝试使用 spring-boot 支持嵌入式 Tomcat。我想将 CXF 用于应用程序中的一组 Web 服务,但我不知道如何支持 CXF servlet。

我的 Main 类看起来像这样......

@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/*");  
  }

}

当我尝试使用典型命令 ./gradlew build && java -jar build/libs/gs-spring-boot-0.1.0.jar 构建和启动 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 添加到应用程序类来修复它。

@Bean
  public ServletRegistrationBean servletRegistrationBean(){
      return new ServletRegistrationBean(new CXFServlet(),"/api/*");
  }

【问题讨论】:

  • 1000 次观看和一票赞成。哎哟!至少给戴夫一些道具。

标签: spring tomcat servlets cxf spring-boot


【解决方案1】:

Spring Boot 嵌入式 servlet 功能旨在与 ServletServletRegistration @Beans 一起使用,而不是与 ContextLoaderListener 一起使用(看起来它试图窃取根上下文的 ServletContext 属性)。尝试为您的 servlet 添加ServletRegistration;如果它是 Spring 感知的,假设它有一个允许您更改应用程序上下文或上下文位置的接口,那么您应该能够在注册时对其进行配置。

【讨论】:

    【解决方案2】:

    我在 github 上找到了以下项目,它帮助我开始了

    https://github.com/ungerts/spring-boot-jaxrs-sample

    为我工作过:

    • spring-boot 1.2.3
    • cxf-rt-frontend-jaxrs:3.1.0
    • jackson-jaxrs-json-provider:2.5.3

    【讨论】:

      【解决方案3】:

      【讨论】:

      • 不要将链接发布为答案,而是添加一些文本来解释此答案如何帮助 OP 解决当前问题。谢谢
      • 好吧,只需将自己的代码替换为 wiki 中示例中更简单的代码即可...
      猜你喜欢
      • 2018-01-05
      • 2018-01-26
      • 1970-01-01
      • 2013-03-22
      • 1970-01-01
      • 1970-01-01
      • 2020-02-25
      • 2017-07-06
      • 2014-05-25
      相关资源
      最近更新 更多