简介:本文详细介绍Java如何通过SOAP协议调用SAP WebService接口,涵盖WSDL解析、请求生成、安全认证、异常处理等核心环节,提供完整代码示例与最佳实践。
SOAP(Simple Object Access Protocol)是基于XML的轻量级协议,通过HTTP/HTTPS传输结构化数据。其核心优势在于跨平台性和严格的消息规范,特别适合企业级系统集成。SAP WebService作为SAP系统的标准接口,遵循WS-I Basic Profile规范,提供RFC函数、BAPI等功能的Web化访问。
SAP系统提供两类WebService接口:
两类接口均通过WSDL(Web Services Description Language)文件描述服务契约,包含操作名称、输入参数、输出结构等关键信息。
<dependencies><!-- JAX-WS标准实现 --><dependency><groupId>com.sun.xml.ws</groupId><artifactId>jaxws-rt</artifactId><version>2.3.5</version></dependency><!-- 或使用Apache CXF --><dependency><groupId>org.apache.cxf</groupId><artifactId>cxf-rt-frontend-jaxws</artifactId><version>3.4.5</version></dependency></dependencies>
通过SAP事务码SOAMANAGER获取WSDL地址:
http://sapserver:8000/sap/bc/srt/wsdl?wsdl=1)使用JDK自带的wsimport工具生成客户端代码:
wsimport -keep -p com.sap.webservice.client http://sapserver:8000/sap/bc/srt/wsdl?wsdl=1
生成文件包含:
ZMATERIALService.java)MaterialRequest.java)SAPException.java)
public class SapWebServiceCaller {private static final String WSDL_URL = "http://sapserver:8000/sap/bc/srt/wsdl?wsdl=1";public static void main(String[] args) {try {// 1. 创建服务实例ZMATERIALService service = new ZMATERIALService(new URL(WSDL_URL));// 2. 获取端口(Port)ZMATERIALPortType port = service.getZMATERIALPort();// 3. 构建请求对象MaterialRequest request = new MaterialRequest();request.setMaterialNumber("MAT-001");request.setPlant("1000");// 4. 调用服务方法MaterialResponse response = port.getMaterialDetails(request);// 5. 处理响应System.out.println("Material Desc: " + response.getDescription());} catch (Exception e) {e.printStackTrace();}}}
SAP WebService通常需要以下认证方式:
// 在获取端口后设置认证信息((BindingProvider)port).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "sap_user");((BindingProvider)port).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "sap_password");
// 创建SSL上下文SSLContext sslContext = SSLContext.getInstance("TLS");sslContext.init(keyManagers, trustManagers, new SecureRandom());// 配置HTTP客户端Client client = ClientProxy.getClient(port);HTTPConduit http = (HTTPConduit) client.getConduit();TLSClientParameters tlsParams = new TLSClientParameters();tlsParams.setSSLContext(sslContext);http.setTlsClientParameters(tlsParams);
启用JAX-WS日志记录:
System.setProperty("com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump", "true");System.setProperty("com.sun.xml.ws.transport.http.HttpAdapter.dump", "true");
// 设置连接超时(毫秒)((BindingProvider)port).getRequestContext().put("com.sun.xml.ws.request.timeout", 5000);// 设置读取超时((BindingProvider)port).getRequestContext().put("com.sun.xml.ws.connect.timeout", 3000);
现象:PKIX path building failed错误
解决方案:
openssl s_client -connect sapserver:443 -showcerts </dev/null | openssl x509 -outform PEM > sap_cert.pem
keytool -importcert -alias sap_cert -keystore $JAVA_HOME/lib/security/cacerts -file sap_cert.pem
现象:Namespace conflict错误
解决方案:
<bindings xmlns:tns="http://sap.com/xi/WebService/sd"><enableAsyncMapping>false</enableAsyncMapping><enableWrapperStyle>false</enableWrapperStyle></bindings>
优化方案:
@MTOM(enabled = true)public interface ZMATERIALPortType { ... }
连接池管理:使用Apache HttpClient连接池
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();cm.setMaxTotal(20);cm.setDefaultMaxPerRoute(5);
异常重试机制:
int retryCount = 0;while (retryCount < 3) {try {return port.getMaterialDetails(request);} catch (SOAPFaultException e) {if (retryCount >= 2) throw e;Thread.sleep(1000 * retryCount);retryCount++;}}
性能监控:集成Micrometer计量库
MeterRegistry registry = new SimpleMeterRegistry();Timer timer = registry.timer("sap.call.duration");timer.record(() -> {// 调用SAP服务});
sap-webservice-client/├── src/main/java/│ ├── com/sap/client/│ │ ├── config/SapClientConfig.java // 配置类│ │ ├── service/SapMaterialService.java // 业务封装│ │ └── model/MaterialRequest.java // 请求对象├── src/main/resources/│ └── sap-config.properties // 配置文件└── pom.xml
通过本文的详细解析,开发者可以系统掌握Java调用SAP WebService接口的全流程技术实现,包括安全认证、异常处理、性能优化等关键环节。实际项目中建议结合Spring Boot框架进行封装,实现更优雅的集成方案。