Spring Boot 3迁移:如何使用JaxWsPortProxyFactoryBean或替代方案?
升级Spring Boot 3替代JaxWsPortProxyFactoryBean方案
Spring Framework 6(Spring Boot 3基于该框架)已移除org.springframework.remoting.jaxws包下的所有类,原因是JAX-WS属于旧Java EE技术栈,Spring 3已全面转向Jakarta EE生态,且官方不再维护这类远程调用组件。以下是两种可行的替代方案:
方案一:使用Apache CXF实现代理客户端
Apache CXF是成熟的Web服务框架,支持Jakarta EE,提供类似的代理工厂功能,适配Spring Boot 3。
1. 添加依赖(Maven)
<dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-spring-boot-starter-jaxws</artifactId> <version>4.0.3</version> <!-- 选择适配Spring Boot 3的版本 --> </dependency>
2. 改写Bean配置
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; import org.apache.cxf.transport.http.HTTPConduit; import org.apache.cxf.transports.http.configuration.AuthorizationPolicy; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class WebServiceClientConfig { @Bean public My myJaxWsClient() { JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean(); // 设置服务接口 factoryBean.setServiceClass(My.class); // 设置服务端点地址 factoryBean.setAddress("http://someuri:7979/myservice"); // 配置Basic认证的用户名密码 My client = (My) factoryBean.create(); HTTPConduit conduit = (HTTPConduit) org.apache.cxf.frontend.ClientProxy.getClient(client).getConduit(); AuthorizationPolicy authPolicy = new AuthorizationPolicy(); authPolicy.setUserName("username"); authPolicy.setPassword("password"); conduit.setAuthorization(authPolicy); return client; } }
方案二:使用原生Jakarta WS API
直接基于Jakarta WS规范实现客户端,无需依赖Spring特定组件,更轻量化。
1. 添加依赖(Maven)
<!-- Jakarta WS API 规范 --> <dependency> <groupId>jakarta.xml.ws</groupId> <artifactId>jakarta.xml.ws-api</artifactId> </dependency> <!-- Jakarta WS 运行时实现 --> <dependency> <groupId>com.sun.xml.ws</groupId> <artifactId>jaxws-rt</artifactId> <scope>runtime</scope> </dependency>
2. 改写Bean配置
import jakarta.xml.ws.BindingProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class WebServiceClientConfig { @Bean public My myJaxWsClient() { // 使用WSDL生成的Service类创建端口 My_Service service = new My_Service(); My port = service.getMyPort(); // 方法名需根据实际生成的Service类调整 // 设置端点地址(覆盖WSDL中的默认地址) BindingProvider bindingProvider = (BindingProvider) port; bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://someuri:7979/myservice"); // 配置Basic认证的用户名密码 bindingProvider.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "username"); bindingProvider.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "password"); return port; } }
注意:
getMyPort()方法名需根据你通过WSDL生成的My_Service类实际方法调整,通常格式为get[PortName]Port()。
内容的提问来源于stack exchange,提问作者Johan
相关产品推荐
相关产品推荐

