Spring Boot调用需认证的安全SOAP Web Service的教程与示例问询
Spring Boot 调用带身份认证的SOAP Web Service 实操教程
1. 初始化项目并添加核心依赖
首先创建Spring Boot项目,在pom.xml中添加SOAP服务依赖和代码生成插件:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web-services</artifactId> </dependency> <dependency> <groupId>wsdl4j</groupId> <artifactId>wsdl4j</artifactId> </dependency> </dependencies> <build> <plugins> <!-- JAXB2插件用于根据WSDL自动生成客户端绑定代码 --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxb2-maven-plugin</artifactId> <version>2.5.0</version> <executions> <execution> <id>xjc</id> <goals> <goal>xjc</goal> </goals> </execution> </executions> <configuration> <!-- 生成代码的存放包路径,可自定义 --> <packageName>com.example.soap.client.generated</packageName> <sources> <!-- 替换为你的WSDL文件存放路径 --> <source>src/main/resources/wsdl/target-service.wsdl</source> </sources> </configuration> </plugin> </plugins> </build>
注意:提前把目标服务的WSDL文件下载到项目src/main/resources/wsdl目录下,保证生成的代码和服务端逻辑完全匹配
2. 生成客户端绑定代码
执行Maven命令生成代码:
mvn jaxb2:xjc
生成的代码默认存放在target/generated-sources/jaxb目录下,需要将该目录标记为项目源码目录。
3. 配置带认证的WebServiceTemplate
3.1 自定义SOAP头拦截器
用于在请求头中自动注入username、password、apitoken三个认证参数:
public class AuthHeaderInterceptor implements ClientInterceptor { private final String username; private final String password; private final String apiToken; public AuthHeaderInterceptor(String username, String password, String apiToken) { this.username = username; this.password = password; this.apiToken = apiToken; } @Override public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException { SoapMessage soapMessage = (SoapMessage) messageContext.getRequest(); SoapHeader soapHeader = soapMessage.getSoapHeader(); // 替换为目标服务要求的认证参数命名空间 QName authQName = new QName("http://your-service-namespace.com/auth", "AuthHeader"); SoapElement authElement = soapHeader.addHeaderElement(authQName); // 按服务要求的参数名添加认证字段 SoapElement usernameNode = authElement.addChildElement("username"); usernameNode.setText(username); SoapElement passwordNode = authElement.addChildElement("password"); passwordNode.setText(password); SoapElement tokenNode = authElement.addChildElement("apitoken"); tokenNode.setText(apiToken); return true; } @Override public boolean handleResponse(MessageContext messageContext) throws WebServiceClientException { return true; } @Override public boolean handleFault(MessageContext messageContext) throws WebServiceClientException { return true; } @Override public void afterCompletion(MessageContext messageContext, Exception ex) throws WebServiceClientException { } }
3.2 客户端配置类
@Configuration public class SoapClientConfig { // 配置参数统一放在application.yml中注入 @Value("${soap.service.endpoint}") private String serviceEndpoint; @Value("${soap.auth.username}") private String username; @Value("${soap.auth.password}") private String password; @Value("${soap.auth.apitoken}") private String apiToken; @Bean public Jaxb2Marshaller marshaller() { Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); // 替换为步骤2中生成代码的包路径 marshaller.setContextPath("com.example.soap.client.generated"); return marshaller; } @Bean public WebServiceTemplate webServiceTemplate(Jaxb2Marshaller marshaller) { WebServiceTemplate template = new WebServiceTemplate(); template.setDefaultUri(serviceEndpoint); template.setMarshaller(marshaller); template.setUnmarshaller(marshaller); // 注入自定义认证拦截器 template.setInterceptors(new ClientInterceptor[]{new AuthHeaderInterceptor(username, password, apiToken)}); // 如果服务同时要求HTTP Basic认证,添加以下配置即可 // HttpComponentsMessageSender sender = new HttpComponentsMessageSender(); // sender.setCredentials(new UsernamePasswordCredentials(username, password)); // template.setMessageSender(sender); return template; } }
4. 编写调用逻辑
在application.yml中添加配置:
soap: service: endpoint: https://your-target-service.com/soap/api auth: username: 你的账号 password: 你的密码 apitoken: 你的接口令牌
编写服务调用类:
@Service public class SoapInvokeService { private final WebServiceTemplate webServiceTemplate; // 构造器注入WebServiceTemplate public SoapInvokeService(WebServiceTemplate webServiceTemplate) { this.webServiceTemplate = webServiceTemplate; } public ServiceResponse callTargetService(ServiceRequest request) { // ServiceRequest、ServiceResponse都是步骤2生成的实体类,替换为你实际的类名即可 return (ServiceResponse) webServiceTemplate.marshalSendAndReceive(request); } }
5. 调试与排查
如果出现调用异常,可在配置文件中开启SOAP报文日志,查看请求参数是否正确:
logging: level: org.springframework.ws.client.MessageTracing.sent: DEBUG org.springframework.ws.client.MessageTracing.received: DEBUG
常见问题排查点:
- 认证失败:检查SOAP头中认证参数的命名空间、字段名是否和服务要求完全一致
- 序列化错误:检查生成代码的包路径是否和
Jaxb2Marshaller配置的上下文路径一致 - 连接异常:确认网络可访问目标服务地址,若有代理需额外配置请求代理
内容的提问来源于stack exchange,提问作者Nero
相关产品推荐
相关产品推荐

