Web 服務作為異構系統互操作的標準化技術,通過 SOAP/XML 消息交換、WSDL 服務描述、UDDI 服務發現,實現跨平台、跨語言的松耦合集成。本文基於 Systinet WASP 平台,演示從現有 Java 聊天業務邏輯到 SOAP Web 服務的完整轉化過程,包含服務端發布、WSDL 生成、客戶端代碼生成與調用全流程。
| 概念 | 說明 | 對應標準 |
|---|---|---|
| SOAP | 簡單對象訪問協議,定義 XML 消息結構 | W3C SOAP 1.1/1.2 |
| WSDL | Web 服務描述語言,描述接口、綁定、端點 | W3C WSDL 1.1 |
| UDDI | 通用描述發現集成,服務註冊發現目錄 | OASIS UDDI |
| Endpoint | 服務訪問地址 (URI) | HTTP/HTTPS |
package com.systinet.simplechat.server.iface;
public interface IChatService {
// 發送消息
void sendMessage(ChatMessage msg);
// 獲取歷史消息
List getMessages(String userId, long sinceTimestamp);
// 註冊用戶
ChatPerson registerUser(String name);
}
// 聊天消息
public class ChatMessage implements Serializable {
private String id;
private ChatPerson sender;
private String content;
private long timestamp;
// getter/setter...
}
// 參與者
public class ChatPerson implements Serializable {
private String id;
private String name;
// getter/setter...
}
package com.systinet.simplechat.server.impl;
public class ChatService implements IChatService {
private SimpleBackend backend; // 委托給後端實現
public ChatService() {
this.backend = SimpleBackendImpl.getInstance(); // 單例後端
}
public void sendMessage(ChatMessage msg) {
backend.addMessage(msg);
}
public List getMessages(String userId, long since) {
return backend.getMessages(userId, since);
}
public ChatPerson registerUser(String name) {
return backend.registerUser(name);
}
}
// 簡單後端:內存存儲,生產環境換成 JDBC/JPA/Redis
class SimpleBackendImpl {
private List messages = Collections.synchronizedList(new ArrayList<>());
private Map users = new ConcurrentHashMap<>();
public void addMessage(ChatMessage msg) { messages.add(msg); }
public List getMessages(String userId, long since) { /* 過濾返回 */ }
public ChatPerson registerUser(String name) { /* 創建用戶 */ }
}
package com.systinet.simplechat.server.impl;
import org.systinet.wasp.Wasp;
import org.systinet.wasp.webservice.Registry;
public class ChatServerApp {
public static void main(String[] args) throws Exception {
// 1. 啟動嵌入式 HTTP/SOAP 服務器
Wasp.startServer("https://localhost:6060");
// 2. 程序化發布 POJO 為 Web 服務
Registry.publish("/ChatService/", ChatService.class);
System.out.println("Chat Server running at https://localhost:6060/ChatService/");
System.out.println("WSDL at https://localhost:6060/ChatService/wsdl");
}
}
關鍵點:
Wasp.startServer() 啟動內嵌 Servlet 容器 (Jetty/Tomcat)Registry.publish() 自動生成 WSDL、處理 SOAP 請求路由、實例管理https://host:port/ChatService/https://host:port/ChatService/wsdl在 IDE (Eclipse + WASP Developer) 中:File → Import → WSDL from Internet,輸入 https://localhost:6060/ChatService/wsdl
右鍵 WSDL 文件 → Generate Client,生成:
com.systinet.simplechat.client.iface.ChatService (服務接口)ChatMessage, ChatPerson (數據結構)ChatServiceClient.java (調用樣例代碼)public class ChatClient {
public static void main(String[] args) throws Exception {
String wsdlURL = "https://localhost:6060/ChatService/wsdl";
// 1. 創建服務代理 (隱藏 SOAP 細節)
ServiceClient serviceClient = ServiceClient.create(wsdlURL, ChatService.class);
serviceClient.setServiceURL("https://localhost:6060/ChatService/");
serviceClient.setWSDLServiceName(new QName(
"https://systinet.com/wsdl/com/systinet/simplechat/server/impl/", "ChatService"));
serviceClient.setWSDLPortName("ChatService");
// 2. 獲取類型安全的服務接口
ChatService service = (ChatService) Registry.lookup(serviceClient);
// 3. 業務調用 (像本地方法一樣)
ChatPerson me = service.registerUser("Alice");
service.sendMessage(new ChatMessage(me, "Hello SOAP Web Service!"));
List msgs = service.getMessages(me.getId(), 0);
msgs.forEach(m -> System.out.println(m.getSender().getName() + ": " + m.getContent()));
}
}
簡化調用 (WASP 便捷 API):
ChatService service = (ChatService) Registry.lookup(
"https://localhost:6060/ChatService/wsdl", ChatService.class);
<soap:Envelope xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:sendMessage xmlns:ns1="...">
<msg>
<id>msg-123</id>
<sender><id>user-456</id><name>Alice</name></sender>
<content>Hello!</content>
<timestamp>1705300000000</timestamp>
</msg>
</ns1:sendMessage>
</soap:Body>
</soap:Envelope>
<wsdl:definitions targetNamespace="...">
<wsdl:types>
<xsd:schema>
<xsd:complexType name="ChatMessage">...</xsd:complexType>
<xsd:complexType name="ChatPerson">...</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="sendMessageRequest">
<wsdl:part name="msg" element="tns:ChatMessage"/>
</wsdl:message>
<wsdl:portType name="ChatService">
<wsdl:operation name="sendMessage">
<wsdl:input message="tns:sendMessageRequest"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ChatServiceSOAP" type="tns:ChatService">
<soap:binding style="document" transport="https://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="sendMessage">
<soap:operation soapAction=""/>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ChatService">
<wsdl:port name="ChatService" binding="tns:ChatServiceSOAP">
<soap:address location="https://localhost:6060/ChatService/"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
| 維度 | JAX-RPC / WASP (舊) | JAX-WS (Java EE 5+) | Spring Boot / JAX-RS (現代) |
|---|---|---|---|
| 編程模型 | 接口 + 實現類 | @WebService 註解 POJO | @RestController / @Endpoint |
| 配置方式 | 部署描述符 / API | 註解 + 少量 XML | 自動配置 + 註解 |
| 客戶端生成 | wscompile / IDE | wsimport (JDK 自帶) | OpenAPI Generator / Feign |
| 數據綁定 | JAX-RPC 映射 | JAXB 2.x | Jackson / JAXB |
| 傳輸協議 | SOAP 1.1 | SOAP 1.1/1.2 | REST/JSON, gRPC, GraphQL |
| 運行時 | 專有容器 | Java EE 容器 / Metro | 內嵌 Tomcat/Jetty/Undertow |
// Spring Boot + JAX-WS (兼容現有 SOAP 客戶端)
@SpringBootApplication
public class ChatApplication {
public static void main(String[] args) {
SpringApplication.run(ChatApplication.class, args);
}
}
@WebService(endpointInterface = "com.example.IChatService")
@Service
public class ChatServiceImpl implements IChatService {
@Autowired ChatRepository repo;
// 實現業務方法...
}
// 配置端點發布
@Configuration
public class WebServiceConfig {
@Bean
public Endpoint chatEndpoint(ChatServiceImpl impl) {
Endpoint endpoint = Endpoint.publish("/ChatService/", impl);
return endpoint;
}
}
本文完整演示了「POJO 業務邏輯 → 運行時發布 SOAP 服務 → WSDL 驅動客戶端生成 → 類型安全調用」的經典 Web 服務開發全流程。雖然 Systinet WASP 等早期商業平台已退出歷史舞台,但 SOAP/Web 服務標準在企業級集成、金融支付、政府互聯等強契約場景仍廣泛使用。現代 Java 開發者應掌握 JAX-WS 標準 API、Spring Boot 集成、以及 REST/gRPC 等輕量級替代方案,根據業務場景選擇最適技術棧。