首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 調用 .NET WebService 實戰:手工構建 SOAP 請求解決互操作難題

     編輯:Java 綜合教學

Java 調用 .NET WebService 實戰:手工構建 SOAP 請求解決互操作難題

項目中需要 Java 調用 .NET 編寫的 WebService,嘗試過 JAX-WS、Axis、CXF 等框架生成客戶端代碼,但因 WSDL 差異、命名空間衝突、複雜類型映射等問題屢屢拋異常。最終採用原生 HttpURLConnection 手工構建 SOAP 消息,繞過框架限制,成功實現互通。下面分享完整工具類代碼與關鍵點解析。

核心代碼:QueryDataUtil


public class QueryDataUtil {
    public static String getOpdetailString(String regionId, String regionName, String signalName) throws Exception {
        // 1. 構建 SOAP 請求報文
        StringBuilder xml = new StringBuilder();
        xml.append("");
        xml.append("");
        xml.append("");
        xml.append("");
        xml.append("")
           .append("").append(regionId).append("")
           .append("").append(regionName).append("")
           .append("").append(signalName).append("")
           .append("");
        xml.append("");

        // 2. 發送 HTTP POST 請求
        String urlString = "https://IP:端口/xxxx?wsdl"; // 替換為真實地址
        HttpURLConnection httpConn = null;
        OutputStream out = null;
        StringBuilder response = new StringBuilder();

        try {
            // 批次號(可選)
            String batchNo = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
            System.out.println("開始調用,批次:" + batchNo);

            httpConn = (HttpURLConnection) new URL(urlString).openConnection();
            httpConn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
            httpConn.setRequestProperty("SOAPAction", "xxx"); // 必須與 .NET 端一致
            httpConn.setRequestMethod("POST");
            httpConn.setDoOutput(true);
            httpConn.setDoInput(true);
            httpConn.setConnectTimeout(10000);
            httpConn.setReadTimeout(30000);
            httpConn.connect();

            out = httpConn.getOutputStream();
            out.write(xml.toString().getBytes("UTF-8"));
            out.flush();

            // 3. 處理響應
            int code = httpConn.getResponseCode();
            InputStream is = (code == HttpURLConnection.HTTP_OK) 
                ? httpConn.getInputStream() : httpConn.getErrorStream();
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"))) {
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
            }
            System.out.println("響應報文:" + response);
            return response.toString();
        } finally {
            if (out != null) try { out.close(); } catch (IOException ignored) {}
            if (httpConn != null) httpConn.disconnect();
        }
    }
}

關鍵坑點與解決方案

問題原因解決
命名空間不匹配.NET 默認用 tempuri.org,Java 框架生成的 stub 可能不同手工構建 XML 時完全按 WSDL 定義寫死命名空間
SOAPAction 為空或錯誤.NET 要求精確的 SOAPAction Header抓包(Wireshark/SoapUI)獲取真實值,填入 setRequestProperty("SOAPAction", "...")
編碼亂碼雙端編碼不一致統一 UTF-8:XML 聲明、HTTP Header、OutputStream/InputStreamReader 都指定 UTF-8
複雜類型序列化失敗框架無法正確映射 .NET 的 DataSet、ArrayOfXxx 等手工拼裝 XML 完全可控,避開映射層
超時/連接失敗網絡、防火牆、服務端處理慢設置連接/讀取超時;生產環境建議用連接池

進階建議

  1. 封裝為通用客戶端:提取公共方法 sendSoapRequest(url, soapAction, xmlBody),業務層只管組裝 Body。
  2. 引入日誌與監控:記錄請求/響應報文、耗時、錯誤碼,便於排查。
  3. 考慮升級為 Apache HttpClient / OkHttp:支持連接池、重試、攔截器,生產級更穩健。
  4. 契約測試:用 SoapUI 對照 WSDL 回歸測試,確保雙端變更不破壞兼容。

當框架成阻礙時,回歸 HTTP+XML 本質往往是最快的破局之道。這份代碼已在多個 .NET 互操作項目中驗證可用,歡迎根據實際 WSDL 微調命名空間與字段名。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved