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

基於 Java Web 服務 (JAX-WS/SOAP) 構建聊天應用完整教程

     編輯:Java 相關知識

前言

Web 服務作為異構系統互操作的標準化技術,通過 SOAP/XML 消息交換、WSDL 服務描述、UDDI 服務發現,實現跨平台、跨語言的松耦合集成。本文基於 Systinet WASP 平台,演示從現有 Java 聊天業務邏輯到 SOAP Web 服務的完整轉化過程,包含服務端發布、WSDL 生成、客戶端代碼生成與調用全流程。

Web 服務核心概念速覽

概念說明對應標準
SOAP簡單對象訪問協議,定義 XML 消息結構W3C SOAP 1.1/1.2
WSDLWeb 服務描述語言,描述接口、綁定、端點W3C WSDL 1.1
UDDI通用描述發現集成,服務註冊發現目錄OASIS UDDI
Endpoint服務訪問地址 (URI)HTTP/HTTPS

聊天業務邏輯層設計 (POJO,無框架依賴)

接口定義

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) { /* 創建用戶 */ }
}

運行時發布為 Web 服務 (Systinet WASP)

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/
  • WSDL 位置:https://host:port/ChatService/wsdl

客戶端開發:從 WSDL 生成代碼調用

步驟 1:下載 WSDL 文件

在 IDE (Eclipse + WASP Developer) 中:File → Import → WSDL from Internet,輸入 https://localhost:6060/ChatService/wsdl

步驟 2:生成客戶端存根

右鍵 WSDL 文件 → Generate Client,生成:

  • com.systinet.simplechat.client.iface.ChatService (服務接口)
  • ChatMessage, ChatPerson (數據結構)
  • ChatServiceClient.java (調用樣例代碼)

步驟 3:客戶端調用代碼

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 消息示例

<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 關鍵片段

<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>

現代 Java Web 服務開發對比

維度JAX-RPC / WASP (舊)JAX-WS (Java EE 5+)Spring Boot / JAX-RS (現代)
編程模型接口 + 實現類@WebService 註解 POJO@RestController / @Endpoint
配置方式部署描述符 / API註解 + 少量 XML自動配置 + 註解
客戶端生成wscompile / IDEwsimport (JDK 自帶)OpenAPI Generator / Feign
數據綁定JAX-RPC 映射JAXB 2.xJackson / JAXB
傳輸協議SOAP 1.1SOAP 1.1/1.2REST/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 等輕量級替代方案,根據業務場景選擇最適技術棧。

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