在異構系統整合中,Java 客戶端常需調用 .NET (ASMX/WCF) WebService 或 Apache XML-RPC 服務(如 MetaWeblog API)。引入 Axis、CXF、JAX-WS 等重型棧會顯著增加部署複雜度。本文提供一個 零第三方依賴、純 JDK 實現 的 SOAPClient4XG 工具類,僅用 HttpURLConnection 發送原始 XML,適合快速測試、輕量集成或受限環境。
byte[]。HttpURLConnection,設置 POST、Content-Type: text/xml; charset=utf-8、SOAPAction、Content-Length。public class SOAPClient4XG {
public static void main(String[] args) throws Exception {
if (args.length < 2) {
System.err.println("Usage: java SOAPClient4XG [soapAction]");
System.exit(1);
}
String urlStr = args[0];
String xmlFile = args[1];
String soapAction = args.length > 2 ? args[2] : "";
byte[] body = readFileToBytes(xmlFile);
HttpURLConnection conn = (HttpURLConnection) new URL(urlStr).openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
conn.setRequestProperty("SOAPAction", soapAction);
conn.setRequestProperty("Content-Length", String.valueOf(body.length));
conn.setDoOutput(true);
conn.setDoInput(true);
try (OutputStream out = conn.getOutputStream()) {
out.write(body);
}
try (BufferedReader in = new BufferedReader(
new InputStreamReader(conn.getInputStream(), "utf-8"))) {
String line;
while ((line = in.readLine()) != null) System.out.println(line);
}
}
private static byte[] readFileToBytes(String path) throws IOException {
try (FileInputStream fin = new FileInputStream(path);
ByteArrayOutputStream bout = new ByteArrayOutputStream()) {
byte[] buf = new byte[4096];
int len;
while ((len = fin.read(buf)) != -1) bout.write(buf, 0, len);
return bout.toByteArray();
}
}
}
loginReq.xml)<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="https://www.w3.org/2001/XMLSchema"
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<UserLoginReq xmlns="https://tempuri.org/">
<UserAcc>baozheng</UserAcc>
<UserPwd>mypwd</UserPwd>
</UserLoginReq>
</soap:Body>
</soap:Envelope>
UserLoginReq、參數 UserAcc/UserPwd 需與 C# 端 [WebMethod] 簽名完全一致(順序可不同)。https://tempuri.org/ 若 C# 未自定義則保持默認。public struct UserLoginResp { public string UserAcc; public int Result; }
[WebMethod]
public UserLoginResp UserLoginReq(string UserAcc, string UserPwd, int ReqFrom) { ... }
.NET 會自動將返回結構序列化為 SOAP 回應。
javac SOAPClient4XG.java
java -cp . SOAPClient4XG https://localhost/BokeServices/Service1.asmx loginReq.xml "https://tempuri.org/UserLoginReq"
rpc.xml)<?xml version="1.0" encoding="utf-8"?>
<methodCall>
<methodName>metaWeblog.deletePost</methodName>
<params>
<param><value>appKeyValue</value></param>
<param><value>746</value></param>
<param><value>baozheng</value></param>
<param><value>Hello123</value></param>
</params>
</methodCall>
java -cp . SOAPClient4XG https://192.168.25.97:8080/BokeeXmlRpc/xml-rpc rpc.xml
main 改為 postXml(String url, String xml, String soapAction) 返回 String,便於單元測試與業務代碼調用。conn.setConnectTimeout(5000)、setReadTimeout(10000),配合指數退避重試。TrustManager 或導入憑證。javax.xml.soap (SAAJ) 動態構建 Envelope,避免手寫 XML 錯誤。javax.xml.parsers 或 DOM4J 解析回應 XML,提取業務數據而非僅打印。SOAPClient4XG 雖簡陋,卻以「零依賴、原生 HTTP、可見原始報文」三大優勢,成為跨平台 WebService 快速驗證、輕量集成的利器。生產環境建議遷移至成熟框架(CXF/JAX-WS),但保留此類工具作為除錯備胎極具價值。