带有 tomcat 和 cxf-servlet 的 spring-boot

标签 spring tomcat servlets cxf spring-boot

我正在尝试用 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

我得到了多个上下文的异常。

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

最佳答案

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

关于带有 tomcat 和 cxf-servlet 的 spring-boot,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24002089/

相关文章:

spring - 使用Spring HATEOAS ControllerLinkBuilder和Kotlin会引发IllegalArgumentException

java - Docker tomcat 编辑扩展的 war 文件

tomcat - wsdl 中的 Progress Application Server 无效 webapp

java - Tomcat本地主机-405错误方法不允许

security - 在父上下文与子上下文中声明 Spring Bean

java - ServletFileUpload.parseRequest() 需要 RequestContext 而不是 HttpServletRequest 请求

java - 防止并发访问 servlet 中的方法

java - 如何使用Apache Kafka实现 "Exactly once"kafka消费者?

spring - 如何在 Grails 中动态选择服务

java - 使用 Spring 实现基于 token 的授权的最佳方法是什么?