You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中@RestController与Apache CXF SOAP服务共存配置求助

让Spring Boot中REST与CXF SOAP服务共存于/ws前缀下的解决方案

你的问题核心在于*CXFServlet拦截了所有/ws/路径的请求,导致原本由Spring MVC DispatcherServlet处理的REST接口请求被CXF接管,从而失效。下面提供几种可行的解决方案,按推荐程度排序:

方案一:使用CXF与Spring MVC集成(推荐)

这种方式让CXF服务和REST服务共享Spring的DispatcherServlet,无需单独注册CXFServlet,从根本上避免了Servlet映射冲突。

步骤1:添加必要依赖

如果用Maven,在pom.xml中添加CXF的Spring MVC集成依赖(确保版本和你的CXF starter一致):

<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
    <version>3.6.2</version> <!-- 替换为你的CXF版本 -->
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http-spring-mvc</artifactId>
    <version>3.6.2</version>
</dependency>

步骤2:配置CXF Endpoint

编写CXF配置类,使用SpringMvcEndpointServletRegistration替代普通的ServletRegistrationBean:

import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.http.spring.SpringMvcEndpointServletRegistration;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.xml.ws.Endpoint;

@Configuration
public class CxfSoapConfig {

    // 注入你的SOAP服务实现类
    @Autowired
    private FindPersonService findPersonService;

    @Bean
    public Endpoint soapEndpoint() {
        EndpointImpl endpoint = new EndpointImpl(findPersonService);
        // 这里设置的地址会拼接在/ws/后面,最终SOAP地址是/ws/findPerson
        endpoint.publish("/findPerson");
        return endpoint;
    }

    @Bean
    public SpringMvcEndpointServletRegistration cxfMvcRegistration() {
        // 将CXF服务绑定到/ws/*路径,由Spring MVC DispatcherServlet统一处理
        return new SpringMvcEndpointServletRegistration(new CXFServlet(), "/ws/*");
    }
}

这样配置后,你的REST接口(比如@GetMapping("/ws/person"))和SOAP接口(/ws/findPerson)会由同一个DispatcherServlet处理,不会再出现冲突。

方案二:精确映射CXFServlet到SOAP服务路径

如果你不想修改依赖或集成方式,可以调整CXFServlet的映射规则,只让它处理SOAP服务的精确路径,而非整个/ws/*:

修改你的CXFServlet注册代码:

@Bean
public ServletRegistrationBean cxfServletRegistration() {
    ServletRegistrationBean<CXFServlet> registration = new ServletRegistrationBean<>(new CXFServlet());
    // 只精确匹配SOAP服务的路径,有多个SOAP服务就添加多个映射
    registration.addUrlMappings("/ws/findPerson");
    // 如果还有其他SOAP服务,比如/ws/createPerson,继续添加
    // registration.addUrlMappings("/ws/createPerson");
    return registration;
}

这种方式下,只有请求精确匹配/ws/findPerson时才会被CXFServlet处理,其他/ws前缀的请求(比如/ws/person)会正常被Spring MVC处理,REST服务就能恢复。

方案三:拆分路径前缀(扩展性好)

如果你的服务数量较多,推荐将REST和SOAP服务的路径前缀拆分,让结构更清晰:

步骤1:调整CXFServlet映射

@Bean
public ServletRegistrationBean cxfServletRegistration() {
    // 让CXF处理/ws/soap/*下的所有SOAP请求
    return new ServletRegistrationBean(new CXFServlet(), "/ws/soap/*");
}

步骤2:配置SOAP Endpoint

@Bean
public Endpoint soapEndpoint() {
    EndpointImpl endpoint = new EndpointImpl(findPersonService);
    // SOAP服务地址最终为/ws/soap/findPerson
    endpoint.publish("/findPerson");
    return endpoint;
}

步骤3:调整REST接口路径

将REST接口的路径调整为/ws/rest/person(保持和SOAP路径区分):

@RestController
@RequestMapping("/ws/rest")
public class PersonRestController {

    @GetMapping("/person")
    public Person getPerson() {
        // 实现逻辑
    }
}

这种方式不仅解决了冲突,还让两种服务的路径结构更清晰,后期维护和扩展更方便。


内容的提问来源于stack exchange,提问作者NAZEHA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:48:20