對方提供 C# 寫的舊式 ASMX WebService:bin 目錄含 DLL、web.config、ws.asmx(指向 YC.Controller.API.ControllerWS)、Word 文檔說明接口。Java 端需調用。
ASMX 不是 DLL 直接調用的庫,而是運行在 IIS 上的 HTTP 端點。對方給的文件是**部署包**,需在 Windows Server 上部署到 IIS,形成可訪問的 URL(如 https://host:port/Service/ws.asmx),Java 才能通過 HTTP/SOAP 調用。
ws.asmx 能看到服務描述頁面、WSDL 鏈接(?wsdl);WSDL 地址:https://host:port/Service/ws.asmx?wsdl
# 方案一:wsimport (JDK 內置,推薦)
wsimport -keep -p com.example.client "https://host:port/Service/ws.asmx?wsdl"
# 方案二:Maven 插件 (cxf-codegen-plugin)
# pom.xml 添加插件配置,mvn generate-sources 自動生成
# 方案三:IDE 圖形化
# IntelliJ: New > Web Service Client > WSDL URL
# Eclipse: New > Other > Web Services > Web Service Client
生成產物:Service 接口、ServiceSoap 端口接口、請求/響應對象、ObjectFactory、package-info.java 等。
// 構建服務工廠與端口
Service service = new Service(new URL("https://host:port/Service/ws.asmx?wsdl"),
new QName("https://tempuri.org/", "Service"));
ServiceSoap port = service.getServiceSoap(); // 或 getServiceSoap12()
// 設置超時(針對 JAX-WS RI)
BindingProvider bp = (BindingProvider) port;
bp.getRequestContext().put(BindingProvider.CONNECT_TIMEOUT, 5000);
bp.getRequestContext().put(BindingProvider.REQUEST_TIMEOUT, 10000);
// 調用業務方法(根據 WSDL 定義的方法名)
GetUserResponse response = port.getUser(new GetUserRequest("user123"));
System.out.println("用戶: " + response.getUser().getName());
| 問題 | 原因 | 解決 |
|---|---|---|
| 命名空間不匹配 | C# 默認 tempuri.org,Java 生成代碼需一致 |
檢查 @WebService(targetNamespace="...") 或手動修改生成代碼 QName |
| 日期類型序列化異常 | C# DateTime ↔ Java XMLGregorianCalendar |
使用 DatatypeFactory.newInstance().newXMLGregorianCalendar(gregorianCalendar) 轉換 |
| 數組/集合為 null | C# 返回 List<T> 或 T[],JAXB 生成 List<T> 需初始化 |
調用前 request.getItems().add(item) 而非 setItems |
| SOAP 版本不匹配 | ASMX 支持 Soap1.1/1.2,端口名不同 | 嘗試 getServiceSoap() (1.1) 或 getServiceSoap12() (1.2) |
| 中文亂碼 | 編碼不一致 | 確保雙方 UTF-8,SOAP 頭聲明 <?xml version="1.0" encoding="UTF-8"?> |
Java 調用 C# ASMX 的關鍵在於:**對方必須將服務部署到 IIS 形成可訪問的 WSDL 端點**,Java 端通過 wsimport 生成客戶端存根進行 SOAP 調用。注意命名空間、日期、集合、SOAP 版本等互操作細節。條件允許,強烈建議雙方協商遷移至 REST/JSON 協議。