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

BPEL 業務流程整合 J2EE 與 .NET Web 服務異構互操作實戰

     編輯:Java 相關知識

背景與挑戰

企業常同時擁有 J2EE 與 .NET 平台的細粒度業務服務。BPEL 作為 SOA 編排標準,基於 WSDL/XML Schema 定義流程,但異構平台間的互操作性問題(XML 命名空間、復雜類型數組、日期時間類型)往往導致集成失敗。關鍵在於先設計 XSD Schema,再生成代碼(契約優先),而非反向生成 WSDL。

業務場景:採購報價流程

  • Buyer:發起請求的客戶端
  • Agent (BPEL 流程):並行調用供應商獲取報價,匯總返回
  • Supplier A (J2EE Web Service):簡單產品信息
  • Supplier B (.NET Web Service):含日期數組的復雜產品信息

Supplier A:J2EE Web Service 開發

1. 設計 XML Schema (SupplierASchema.xsd)

  • 目標命名空間:https://schema.a.supplier(域名反寫避免包名衝突)
  • 定義 Product complexType:_name(string)、_price(float)、_qty(int)、_refurbished(boolean)

2. 設計 WSDL (SupplierAService.wsdl)

  • 導入 Schema,定義 getQuoteRequest/getQuoteResponse 消息
  • PortType 定義 getQuote 操作
  • Binding 選 document/literal,Service 端點地址

3. 生成 Skeleton 並實現

// Product 類添加構造器
public Product(String name, int qty, float price, boolean refurbished) { ... }

// SupplierAQuoteServiceBindingImpl
private static Hashtable inventory = new Hashtable();
public SupplierAQuoteServiceBindingImpl() {
    inventory.put("IBM ThinkPad T40", new Product("IBM ThinkPad T40", 200, 1499.99f, false));
    inventory.put("Dell Inspiron 4000", new Product("Dell Inspiron 4000", 100, 999.99f, true));
}
public Product getQuote(String productName) {
    return inventory.containsKey(productName) ? (Product)inventory.get(productName)
        : new Product(productName, 0, 0f, false);
}

Supplier B:.NET Web Service 開發

1. 設計復雜 Schema (SupplierBSchema.xsd)

  • 目標命名空間:https://schema.b.supplier
  • DateInfo:_date(dateTime)、_desc(string)
  • ArrayOfDateInfo:minOccurs=0, maxOccurs=unbounded 的 DateInfo 元素序列
  • Product:_name、_qty、_price、_dates(ArrayOfDateInfo)
  • 全局元素 productItem (type=Product) 供 xsd.exe 生成類

2. 生成 C# 類並實現 .asmx

// 運行: xsd.exe SupplierBSchema.xsd /classes → SupplierBSchema.cs
// 修改 SupplierBQuoteService.asmx
[WebService(Namespace="https://b.supplier/service")]
public class SupplierBQuoteService {
    private static Hashtable inventory;
    public SupplierBQuoteService() {
        inventory = new Hashtable();
        inventory.Add("IBM ThinkPad T40", new Product("IBM ThinkPad T40", 200, 1399.99f,
            new DateInfo[]{ new DateInfo(DateTime.Now, "Manufacture Date"),
                            new DateInfo(DateTime.Now.AddYears(3), "Expiry Date") }));
        // ... 其他產品
    }
    [WebMethod]
    public Product getQuote(string quoteItemName) {
        return inventory.ContainsKey(quoteItemName) ? (Product)inventory[quoteItemName]
            : new Product(quoteItemName, 0, 0, new DateInfo[]{...});
    }
}

瀏覽器測試 https://localhost/SupplierB/SupplierBQuoteService.asmx?wsdl 確認 WSDL 正確。

構建 Agent BPEL 流程

1. 定義匯總 Schema (QuoteProcessSchema.xsd)

  • 導入 SupplierASchema.xsd、SupplierBSchema.xsd
  • 定義 ProductQuotes:SupplierAQuote(SupplierASchema:Product)、SupplierBQuote(SupplierBSchema:Product)

2. 創建流程接口 WSDL (quoteProcessClient.wsdl)

  • 導入 QuoteProcessSchema.xsd
  • 定義 getQuotesRequest(productName)、getQuotesResponse(quotes:ProductQuotes)

3. WebSphere Integration Developer 可視化建模

  • 創建 QuotesProcess (Sequence-based BPEL)
  • 拖入三個 PartnerLink:Client(quoteProcessClient)、SupplierA(SupplierAService)、SupplierB(SupplierBService)
  • 定義變量:Input(getQuotesRequest)、Output(getQuotesResponse)、SupplierAReq/Res、SupplierBReq/Res
  • Receive (Client.getQuotes) → Flow (並行) →
    • Sequence QuoteSupplierA:Assign(複製 productName) → Invoke(SupplierA.getQuote)
    • Sequence QuoteSupplierB:JavaSnippet(構造 SupplierB 請求) → Invoke(SupplierB.getQuote)
    → JavaSnippet preReply (合併兩個報價到 Output) → Reply (Client.getQuotesResponse)

4. 生成部署代碼並發布

  • 右鍵 BPEL → Generate Deployment Code (SOAP/HTTP, IBM Web Service)
  • 部署 SupplierA EAR、QuoteProcess EAR 到測試服務器

Java 客戶端測試

// 從流程 WSDL 生成 JAX-RPC Proxy
QuotesProcessPortTypeProxy proxy = new QuotesProcessPortTypeProxy();
ProductQuotes result = proxy.getQuotes("IBM ThinkPad T40");

Product quoteA = result.getSupplierAQuote();
Product quoteB = result.getSupplierBQuote();

System.out.println("Supplier A: Qty=" + quoteA.get_qty() + ", Price=" + quoteA.get_price()
    + ", Refurbished=" + quoteA.is_refurbished());
System.out.println("Supplier B: Qty=" + quoteB.get_qty() + ", Price=" + quoteB.get_price());
DateInfo[] dates = quoteB.get_dates().get_dateInfo();
for (DateInfo d : dates) {
    Calendar cal = d.get_date(); Date dt = cal.getTime();
    System.out.println(d.get_desc() + ": " + dt);
}

關鍵互操作性技巧總結

  1. 契約優先:手寫 XSD 定義復雜類型、數組、命名空間,雙端共享
  2. 命名空間策略:JAX-RPC 以域名反寫作包名,需細粒度(如 https://schema.a.supplier)避免衝突
  3. 數組建模:.NET 需顯式 ArrayOfXxx 包裝器類型,minOccurs=0, maxOccurs=unbounded
  4. 日期時間:統一用 xsd:dateTime,Java 映射 Calendar,客戶端轉 Date 顯示
  5. 調試利器:WebSphere 可視化 BPEL 調試器、TCPMon 捕獲 SOAP 報文、服務器跟蹤日誌
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved