Spring Boot访问?wsdl无法获取完整WSDL文件的问题解决
Spring Boot CXF WebService WSDL访问异常排查与修复
问题背景
已自定义WSDL文件,通过如下Spring Boot配置暴露WebService:
@Configuration @EnableWs @Import({CommonConfiguration.class}) public class MyServiceConfiguration extends WsConfigurerAdapter { @Autowired @Qualifier(Bus.DEFAULT_BUS_ID) private SpringBus springBus; public MyService getMyService() { return new MyService(); } @Bean public ServletRegistrationBean<CXFServlet> dispatcherServlet() { return new ServletRegistrationBean<>(new CXFServlet()); } @Bean public DispatcherServletPath dispatcherServletPathProvider() { return () -> ""; } @Bean(name = "myService") public Wsdl11Definition defaultWsdl11Definition() { SimpleWsdl11Definition wsdl11Definition = new SimpleWsdl11Definition(); wsdl11Definition.setWsdl(new ClassPathResource("wsdl/my_service/myService.wsdl")); return wsdl11Definition; } @Bean public Endpoint endpoint() { EndpointImpl endpoint = new EndpointImpl(springBus, getMyService()); endpoint.publish("/services/myService"); return endpoint; } }
预期应用启动后,访问https://localhost:7777/?wsdl可在浏览器查看完整WSDL文件,但实际显示陌生页面;点击页面WSDL链接后,跳转到包含<wsdl:import>的简化WSDL,真实完整WSDL需通过https://localhost:7777/services/myService?wsdl=MyService.wsdl访问。
需解决以下问题:
- 为何访问
?wsdl无法直接获取完整WSDL? - 配置存在哪些问题?
- 如何修复以实现直接访问
?wsdl获取完整WSDL?
原因分析
- 根路径
/?wsdl请求被Spring Boot默认的DispatcherServlet接管,而非CXFServlet,因此返回的不是预期的完整WSDL。 - CXF Endpoint发布在
/services/myService路径下,默认仅该路径下的?wsdl能返回对应服务的WSDL,根路径未关联正确的WSDL资源。 - CXF默认会拆分包含
<wsdl:import>的WSDL,返回简化版并指向外部导入文件,导致直接访问根路径无法获取完整内容。
配置问题点
- CXFServlet映射缺失:
ServletRegistrationBean<CXFServlet>未指定映射路径,CXFServlet仅处理默认路径,根路径请求被Spring MVC DispatcherServlet拦截。 - DispatcherServletPath配置冲突:自定义的
DispatcherServletPath返回空字符串,打乱了Servlet路径映射逻辑,导致根路径请求无法正确路由到CXFServlet。 - WSDL未关联到根路径:定义的
Wsdl11DefinitionBean未与CXF Bus关联,根路径?wsdl无法识别并返回该WSDL。 - WSDL拆分默认开启:CXF默认拆分包含导入的WSDL,返回简化版而非完整内容。
修复方案
1. 修正CXFServlet映射路径
修改dispatcherServlet() Bean,让CXFServlet接管所有路径请求:
@Bean public ServletRegistrationBean<CXFServlet> dispatcherServlet() { ServletRegistrationBean<CXFServlet> servletBean = new ServletRegistrationBean<>(new CXFServlet()); // 映射根路径及所有子路径 servletBean.addUrlMappings("/*"); // 设置CXFServlet优先级高于Spring MVC DispatcherServlet servletBean.setLoadOnStartup(1); return servletBean; }
2. 移除冲突的DispatcherServletPath配置
删除以下代码,避免干扰Servlet路径映射:
// 移除该Bean @Bean public DispatcherServletPath dispatcherServletPathProvider() { return () -> ""; }
3. 配置Bus关联默认WSDL并禁用拆分
添加@PostConstruct方法配置CXF Bus,指定根路径?wsdl返回的WSDL,并禁用拆分:
@PostConstruct public void configureBus() { // 关联定义好的Wsdl11Definition Bean(name为"myService") springBus.setProperty("org.apache.cxf.wsdl.service.factory.DefaultWsdl11Definition", "myService"); // 禁用WSDL拆分,返回完整内容 springBus.setProperty("org.apache.cxf.wsdl.split", false); }
4. 验证WSDL文件路径
确认ClassPathResource("wsdl/my_service/myService.wsdl")路径正确,WSDL文件放置在src/main/resources/wsdl/my_service/目录下,无拼写错误。
完成以上配置后,重启应用,访问https://localhost:7777/?wsdl即可直接获取完整的WSDL文件。
内容的提问来源于stack exchange,提问作者Jack Milo
相关产品推荐
相关产品推荐

