从Axis2迁移到CXF后多端口单服务WSDL生成异常求助
在JakartaEE环境下为CXF WebService绑定多端口的解决方案
1. 先确认原始WSDL的端口结构
确保你的WSService.wsdl中确实包含两个<port>节点,分别对应不同地址和绑定(比如SOAP1.1/1.2或不同传输协议),示例结构如下:
<wsdl:service name="WSService"> <wsdl:port name="WSServiceSOAP11port_http" binding="tns:WSServiceSOAP11Binding"> <soap:address location="http://example.com/ws/soap11"/> </wsdl:port> <wsdl:port name="WSServiceSOAP12port_http" binding="tns:WSServiceSOAP12Binding"> <soap12:address location="http://example.com/ws/soap12"/> </wsdl:port> </wsdl:service>
2. 通过CXF配置文件定义多端点
仅靠@WebService注解无法同时暴露多个端口,需要在CXF的配置文件中显式声明两个端点:
在WEB-INF/cxf-servlet.xml(Web应用)或META-INF/cxf.xml中添加:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <!-- 第一个端点:SOAP1.1端口 --> <jaxws:endpoint id="wsServiceSoap11" implementor="com.example.WSService" address="/WSServiceSOAP11" serviceName="tns:WSService" portName="tns:WSServiceSOAP11port_http" targetNamespace="http://example.com/WSService/"/> <!-- 第二个端点:SOAP1.2端口 --> <jaxws:endpoint id="wsServiceSoap12" implementor="com.example.WSService" address="/WSServiceSOAP12" serviceName="tns:WSService" portName="tns:WSServiceSOAP12port_http" targetNamespace="http://example.com/WSService/"/> </beans>
address是相对于应用上下文的路径,最终访问地址为http://你的域名/应用上下文/WSServiceSOAP11?wsdl和http://你的域名/应用上下文/WSServiceSOAP12?wsdl- 如果是EJB(@Stateless),将
implementor改为EJB的JNDI地址,比如implementor="#ejb:/你的应用名/WSService!com.example.WSService.IWSService"
3. 配合web.xml配置Servlet映射(WAR部署场景)
在web.xml中添加CXF Servlet的多路径映射,确保两个端点都能被访问:
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee" version="10.0"> <servlet> <servlet-name>CXFServlet</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <!-- 映射第一个端点路径 --> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/WSServiceSOAP11/*</url-pattern> </servlet-mapping> <!-- 映射第二个端点路径 --> <servlet-mapping> <servlet-name>CXFServlet</servlet-name> <url-pattern>/WSServiceSOAP12/*</url-pattern> </servlet-mapping> </web-app>
4. 调整wsdl2java生成逻辑
重新执行wsdl2java命令,确保生成包含两个端口的客户端/服务端代码:
wsdl2java -d src/main/java -p com.example.WSService $wsdlDir/WSService.wsdl
生成后会得到WSService_Service类,其中包含getWSServiceSOAP11port_http()和getWSServiceSOAP12port_http()方法,分别对应两个端口。
5. 验证效果
启动应用后,分别访问两个端点的WSDL地址,确认每个WSDL包含对应端口信息。如果需要返回包含两个端口的统一WSDL,可以在端点配置中指定静态WSDL路径并覆盖地址:
<jaxws:endpoint id="wsServiceSoap11" implementor="com.example.WSService" address="/WSServiceSOAP11" serviceName="tns:WSService" portName="tns:WSServiceSOAP11port_http" targetNamespace="http://example.com/WSService/" wsdlLocation="classpath:WSService.wsdl" publishedEndpointUrl="http://你的域名/应用上下文/WSServiceSOAP11"/>
关键注意事项
- 移除
@WebService注解中的portName属性,避免限制单一端口生成 - 确保CXF版本与JakartaEE版本兼容(CXF 4.x对应JakartaEE 9+)
- 若使用EJB,需保证EJB容器与CXF集成正常
内容的提问来源于stack exchange,提问作者Clueless
相关产品推荐
相关产品推荐

