用 WID、WPS和 Adobe Flex 為業務流程應用程式開發富 Web 客戶機

CloudSpace發表於2010-09-21
Jun Xue, 軟體工程師, IBM

簡介: 建立可以使用 WebSphere Process Server 的 Business Flow Manager 和 Human Task Manager Web 服務 API 與業務流程和人工任務互動的富 Adobe® Flex™ Web 客戶機。

簡介

可以使用 WebSphere Process Server V6 設計和管理所有型別的業務流程,尤其是可能包含人工互動的以人為中心的業務流程。通常,J2EE 客戶機使用 Business Flow Manager 和 Human Task Manager J2EE API 與業務流程和人工任務互動。在本文中,介紹如何在 Flex 應用程式中使用 Process Server 提供的 Web 服務 API 與業務流程和人工任務互動。

Process Server 提供兩個 Web 服務介面:

  • Business Flow Manager API (BFM API),它讓客戶機應用程式可以與微型流和長時間執行的過程互動。
  • Human Task Manager API (HTM API),它讓客戶機應用程式可以建立任務、宣告和完成現有的任務等等。

本文包含一個示例企業應用程式過程(其中有一個人工任務活動)和一個與此過程互動的 Flex 客戶機。討論如何使用 Flex 通過發出 Web 服務請求啟動過程、宣告和完成人工任務。還討論如何開發使用 BFM 和 HTM Web 服務 API 訪問在 Business Process Choreographer 環境中執行的業務流程和人工任務的其他 Web 服務客戶機應用程式。

本文的目的是講解如何使用 Flex 建立富 Web 客戶機,讓客戶機通過 BFM 和 HTM Web 服務 API 連線業務流程。本文將帶領您完成以下任務:

  • 建立業務流程應用程式
  • 研究 BFM 和 HTM Web 服務 API
  • 使用 Flex 建立富 Web 客戶機

圖 1 說明示例應用程式的架構。


圖 1. 示例應用程式的架構
示例應用程式的架構

本文假設您有使用 WebSphere Process Server(後面簡稱為 Process Server)和用 WebSphere Integration Developer(後面簡稱為 Integration Developer)開發業務流程應用程式的經驗。還假設您熟悉 Adobe Flex。關於 WebSphere Business Process Management 和相關技術的更多資訊見 參考資料

在開始學習本文之前,一定要安裝和執行以下軟體:

  • WebSphere Integration Developer V6.2:這是一個整合開發環境 (IDE),用於構建基於面向服務架構 (SOA) 的應用程式。
  • WebSphere Process Server V6.2:這是一個高效能的業務流程自動執行時引擎。
  • Adobe Flex Builder 3:這是一個基於 Eclipse 的強大的 IDE,用於開發 Flex 應用程式。

本文的 下載 部分提供以下示例檔案:

  • OrderSampleLibrary.zip 包含預定義的業務物件和介面。
  • OrderSampleProcessModule.zip 包含示例業務流程應用程式專案的原始碼檔案和可以在 Process Server 中安裝的 Enterprise Application Archive (EAR) 檔案 OrderSampleProcess.ear。
  • BizFlexClient.zip 包含 Adobe Flex 專案的原始碼檔案。

下載這些檔案,把 OrderSampleProcessModule.zip 和 BizFlexClient.zip 解壓到本地目錄中。

本文中的示例演示如何構建一個訂購請求過程應用程式,其中包含一個人工任務活動,經理通過這個人工任務批准請求。圖 2 給出示例的業務流程。


圖 2. 示例訂購過程
示例訂購過程

在下面幾節中,要匯入示例庫、建立元件和分配介面以及建立所需的 Java™ 實現。

匯入示例庫

為了構建這個示例,需要匯入 下載 中提供的 OrderSampleLibrary 中的介面和業務物件定義。按以下步驟匯入庫並在 Integration Developer 中建立 Order Process 應用程式模組:

  1. 選擇 File => Import => thers => Project Interchange
  2. 找到並選擇 OrderSampleLibrary.zip,單擊 Finish,見圖 3。

    圖 3. 匯入 OrderSampleLibrary
    匯入 OrderSampleLibrary

  3. 建立模組,選擇 File => New => Module
  4. 指定 OrderSampleProcess 作為 Module name,單擊 Next
  5. Select Required Libraries 對話方塊中,確保選擇 OrderSampleLibrary 並單擊 Finish
  6. 應該會在 Business Integration 檢視中看到 OrderSampleProcess 裝配圖,見圖 4。

    圖 4. Business Integration 檢視中的 OrderSampleProcess
    Business Integration 檢視中的 OrderSampleProcess

建立元件並分配介面

現在 OrderSampleProcess 應用程式可以使用 OrderSampleLibrary 中的業務物件和介面了,接下來可以建立過程、人工任務和 Java™ 元件,在模組中分配對應的介面。

按以下步驟在裝配圖中新增元件:

  1. 建立 Process 元件,開啟裝配編輯器,選擇 Process 並把它拖到編輯器中,把這個元件改名為 OrderProcess。(注意:左下角的驚歎號圖示表示還沒有建立這個元件的實現:稍後建立這個實現。)
  2. 分配介面,右鍵單擊 OrderProcess,選擇 Add => Interface,選擇 NewOrderInterface,然後單擊 OK
  3. 建立 Human Task 元件,開啟裝配編輯器,選擇 Human Task 並把它拖到編輯器中,把這個元件改名為 ManagerApproval
  4. 分配介面,右鍵單擊 ManagerApproval,選擇 Add => Interface,選擇 OrderApprovalInterface,然後單擊 OK
  5. 建立 Java 元件,開啟裝配編輯器,選擇 Java 並把它拖到編輯器中,把這個元件改名為 ProcessOrderService
  6. 分配介面,右鍵單擊 ProcessOrderService,選擇 Add => Interface,選擇 ProcessOrderInterface,然後單擊 OK
  7. 在 Add Wire 對話方塊中單擊 OK,在 OrderProcessManagerApproval 之間以及 OrderProcessProcessOrderService 之間建立連線。
  8. 儲存裝配圖。裝配編輯器的內容應該像圖 5 這樣。

    圖 5. 裝配編輯器
    裝配編輯器

現在已經定義了三個元件,下面可以建立每個元件的實現。

建立 ProcessOrderService 的 Java 實現

當經理批准訂購請求時,過程通過呼叫這個 Java 元件來處理訂購請求。按以下步驟實現它:

  1. 開啟裝配編輯器,右鍵單擊 ProcessOrderService 並選擇 Generate implementation。保持預設設定並單擊 OK
  2. 這時會建立一個 Java 類,其中有一個與 ProcessOrderInterface 中定義的操作同名的方法。在這個方法中新增清單 1 所示的邏輯。

    清單 1. ProcessOrderRequest 方法的實現
    						
    public String processOrderRequest(DataObject orderRequest,DataObject approvalMsg){
        String responseMsg = "This order has been approved, it will be sent to supplier 
    for further processing....."
        System.out.println(responseMsg);
        return  responseMsg;
    }
                

  3. 儲存裝配圖。

建立 ManagerApproval 人工任務的實現

按以下步驟建立 ManagerApproval 人工任務的實現:

  1. 開啟裝配編輯器,右鍵單擊 ManagerApproval 並選擇 Generate implementation。保持預設設定並單擊 OK
  2. 當人工任務編輯器開啟並顯示 ManagerApproval 時,關閉它並儲存裝配圖。

建立 OrderProcess 的實現

OrderProcess 是一個過程元件,其中包含訂購請求的業務邏輯。它接收訂購請求並等待經理批准。這個業務流程是使用 Business Process Execution Language (BPEL) 建模的,在過程編輯器中顯示為一系列活動。按以下步驟使用過程編輯器建立和編輯訂購請求過程:

  1. 接收訂購請求。
  2. 經理人工地批准請求。
  3. 判斷經理是否批准了請求。如果請求被拒絕了,就向使用者傳送一條訊息。如果請求被批准了,就呼叫 ProcessOrderService 繼續處理它。

按以下步驟生成 OrderProcess 元件的實現:

  1. 開啟裝配編輯器,右鍵單擊 OrderProcess 並選擇 Generate implementation。保持預設設定並單擊 OK
  2. 過程編輯器開啟,其中顯示一個基本的業務流程,見圖 6。儲存裝配圖。

    圖 6. 過程編輯器顯示 OrderProcess
    過程編輯器顯示 OrderProcess

  3. 進入過程編輯器的 Properties 檢視並選擇 Details 以開啟過程屬性。
  4. 因為經理可能無法馬上處理請求,應該把這個過程設定為長時間執行的過程。確保選中 Process is long-running,見圖 7。
  5. 我們希望使用者能夠看到響應,所以不希望過程例項被自動刪除。對於 Automatically delete the process after completion 選擇 No

    圖 7. OrderProcess 詳細資訊
    OrderProcess 詳細資訊

  6. 接下來,新增一個全域性變數以儲存經理批准訊息。在 Variables 下面,單擊加號。把這個變數命名為 approvalMsg,選擇 ApprovalResponseBO 作為資料型別,然後單擊 OK。這個變數會新增到變數列表中。
  7. 在過程編輯器皮膚中,把 Structure 類別中的 Generalized Flow 拖放到 ReceiveReply 之間。
  8. Basic Actions 類別中的 Invoke 拖放到 Generalized Flow 結構中,把它的名稱設定為 InvokeTask
  9. 選擇 InvokeTask 活動,然後進入 Properties 檢視並選擇 Details
  10. 在 Details 檢視中(見圖 8),選擇 OrderApprovalInterfacePartner 作為 Partner,選擇 approveOrder 作為 Operation
  11. 在表格中,對於 Input(s),在 approvalMsg 行(最後一列名為 Read From Variable)中選擇 (none)。從下拉選單中選擇 orderRequest 變數。
  12. 對於 Output(s),在 response 行(最後一列名為 Store Into Variable)中選擇 (none)。從下拉選單中選擇 approveMsg 變數。

    圖 8. InvokeTask 活動詳細資訊
    InvokeTask 活動詳細資訊

  13. Structures 類別中的 Choice 拖放到 GeneralizedFlow 結構中,把它的名稱設定為 Choice。把預設 case 改名為 Approve
  14. 在 Properties 檢視中,選擇 Approve case,然後選擇 Details。對於 Expression Language 選擇 XPath 1.0,把條件設定為 $approveMsg/isApproval=true(),見圖 9。

    圖 9. Approve case 詳細資訊
    Approve case 詳細資訊

  15. Choice 活動建立第二個 case:右鍵單擊 Choice,然後選擇 Add a case,把它改名為 Reject
  16. 在 Properties 檢視中,選擇 Reject case,然後選擇 Details。對於 Expression Language 選擇 XPath 1.0,把條件設定為 $approveMsg/isApproval=false(),見圖 10:

    圖 10. Reject case 詳細資訊
    Reject case 詳細資訊

  17. 現在已經在 Choice 活動中建立了兩個 case。對於每個 case,需要建立一個後續活動。把 Basic Actions 類別中的 Invoke 拖放到 Choice 結構中,放在 Approve case 後面,把它的名稱設定為 ProcessOrder
  18. Assign 拖放到 Choice 結構中,放在 Reject case 後面,把它的名稱設定為 RejectedMsg
  19. 在 Properties 檢視中選擇 RejectedMsg 並指定詳細資訊,見圖 11:

    圖 11. RejectedMsg 詳細資訊
    RejectedMsg 詳細資訊

  20. 在 Properties 檢視中指定 ProcessOrder 活動的詳細資訊,見圖 12:

    圖 12. ProcessOrder 詳細資訊
    ProcessOrder 詳細資訊

  21. 在過程編輯器中,右鍵單擊 InvokeTask 並選擇 Add a linkInvokeTask 活動與 Choice 活動連線起來。
  22. 現在,過程的實現已經完成了。儲存它之後,這個過程應該像圖 13 這樣。

    圖 13. OrderProcess 實現
    OrderProcess 實現

OrderSampleProcess 應用程式現在完成了。部署這個應用程式之後,它就可以接收來自 Web 服務客戶機的請求以建立過程並宣告和完成人工任務。在 下載 中可以找到完整的示例。

您需要基本瞭解 BFM 和 HTM Web 服務 API 的功能,因為我們將用 Flex 發出一些 Web 服務呼叫。Business Process Choreographer 提供兩個單獨的 Web 服務介面。BFM API 允許與微型流和長時間執行的過程互動。在本文中,我們用它完成以下操作:

  • 查詢過程模板
  • 建立和啟動過程例項

HTM API 讓客戶機應用程式可以與人工任務互動。在本文中,我們用它完成以下操作:

  • 查詢任務集合
  • 宣告現有的任務
  • 完成任務
  • 傳輸工作項

從 WebSphere Process Server 匯出 WSDL 檔案

為了研究 BFM 和 HTM Web 服務 API,可以從 Process Server 匯出 Web Service Description Language (WSDL) 檔案,稍後將通過它呼叫 Web 服務介面。

按以下步驟匯出 WSDL 檔案:

  1. 確認 Process Server 已經啟動。
  2. 在瀏覽器中登入管理控制檯(預設 URL http://localhost:9060/admin)。
  3. 為了匯出 BFM API WSDL 檔案,在左邊的導航條中選擇 Applications => Enterprise Applications(見圖 14),單擊 BPEContainer_{your_nodename}_server1

    圖 14. BPEContainer 應用程式
    圖 14. BPEContainer 應用程式

  4. 在應用程式的配置頁面中,單擊 Web Services Properties 部分中的 Publish WSDL files,見圖 15。

    圖 15. 應用程式的配置頁面
    圖 15. 應用程式的配置頁面

  5. 選擇 zip 檔案(見圖 16),把它儲存到本地目錄中。

    圖 16. 下載頁面
    圖 16. 下載頁面

  6. 解壓檔案,會看到 WSDL 檔案 BFMWS.wsdl。
  7. 為了匯出 HTM API WSDL 檔案,選擇 Applications => Enterprise Applications 並單擊 TaskContainer_{your_nodename}_server1
  8. 重複以上步驟下載並解壓檔案,會看到 WSDL 檔案 HTMWS.wsdl。

得到 BFM 和 HTM API 的 WSDL 檔案之後,可以使用 Integration Developer WSDL 編輯器開啟並研究它們。關於這些 Web 服務 API 的更多資訊,參見 參考資料 中的文章。

後端的業務流程應用程式已經完成了,現在可以使用 Flex 構建一個富 Web 客戶機,讓它與剛才構建的過程和人工任務互動。BizFlexClient.zip 中包含完整的 Adobe Flex 專案原始碼檔案。如果您還沒有下載並解壓這個檔案,現在就執行這個步驟。

用 Flex 呼叫 BFM 和 HTM Web 服務

在本節中,討論如何用 Flex 呼叫 BFM 和 HTM Web 服務 API。Business Process Choreographer 提供的 Web 服務 API 由 Web 服務安全機制保護。這意味著對 Web 服務介面的所有請求必須包含一個安全令牌,安全令牌代表有效的使用者憑證。

有幾種安全令牌。在我們的示例中,使用 Username 令牌。WSS-SOAP 訊息安全文件中引入了 元素作為一種提供使用者名稱的方法。清單 2 說明 元素的 XML 語法:


清單 2. 的 XML 語法

				

 ... 
 ... 
 ... 
 ... 


按以下步驟用 Flex 呼叫 BFM 和 HTM Web 服務 API:

  1. 建立一個名為 BizFlexClient 的 Flex 專案。
  2. 為了建立一個 Web 服務代理並讓它向遠端 Web 服務伺服器傳送請求,定義一個名為 WSBase.asActionScript 類,它擴充套件超類 mx.rpc.soap.AbstractWebService。這個類編碼 SOAP 請求訊息、把訊息傳送出去並處理結果,還要裝載和解析 WSDL 檔案。
  3. 為了建立 Username 令牌,在 WSBase.as 類中定義一個名為 createWSSEHeader 的函式。
  4. 首先需要設定使用者名稱和密碼。在這裡,已經生成了 元素,密碼以明文形式傳送。最後,createWSSEHeader()(見清單 3)將返回一個 SOAP 頭 XML 訊息,它代表使用者憑證。

    清單 3. 在 WSBase.as 中建立 Username 令牌
    						
    public class WSBase extends AbstractWebService
    {
      	private function createWSSEHeader():XML{
    		if(this._username != null && this._password != null){
      			var userToken:String = "UsernameToken-"
    +Math.round(Math.random()*999999).toString();
      			var wsseHeader:XML =  
                  wsseHeader.setNamespace(SOAP_CONSTS.envelopeNamespace);
                  var nsSecurityString:String = "http://docs.oasis-open.org/wss/2004/01
    /oasis-200401-wss-wssecurity-secext-1.0.xsd";
                  var securityQname:QName = new QName(nsSecurity,"Security");
                  var nsSecurity:Namespace = new Namespace("wsse",nsSecurityString);
                  var headerElem:XML = 
                  headerElem.setNamespace(nsSecurity);
                  headerElem.addNamespace(SOAP_CONSTS.envelopeNamespace);
                  var attrStr:String = SOAP_CONSTS.envelopeNamespace.prefix;
                  headerElem.@[attrStr + ":" + SOAP_CONSTS.mustUnderstandQName.
    localName] = "1"; // Use "1" form. for WS-I compatibility
      			
      			var userNameElem:XML = 
               			
      	            		{this._username}
      	            		
    {this._password}
               			;
                  headerElem.appendChild(userNameElem);
            		wsseHeader.appendChild(headerElem);
            		this._wsseHeader = wsseHeader;
            		return wsseHeader;		
    		}
    		return null;
    	}
    }
    

  5. 為了在 WSBase.as 中編碼 SOAP 訊息,定義一個名為 encodeSOAPMessage 的函式,它把 SOAP Header 元素和 SOAP Body 元素編碼為 SOAP Envelope 元素,見清單 4。這個元素是 SOAP 訊息的根元素。

    清單 4. 在 WSBase.as 中編碼 SOAP 訊息
    						
    protected function encodeSOAPMessage(operationBody:XML):XML{ 
        var envelopeXML:XML = ;
        envelopeXML.setNamespace(SOAP_CONSTS.envelopeNamespace);
        envelopeXML.addNamespace(this._operationNS);
        var wsseHeader:XML = this.createWSSEHeader();
        if(wsseHeader != null){
            envelopeXML.appendChild(wsseHeader); // append the WSSE header
        }	
        // Create SOAP Body element
        var bodyXML:XML = ; 
        bodyXML.setNamespace(SOAP_CONSTS.envelopeNamespace);
        operationBody.setNamespace(this._operationNS);
        bodyXML.appendChild(operationBody);
        envelopeXML.appendChild(bodyXML);
        return envelopeXML;
    }
    

  6. 為了對遠端 Web 服務伺服器執行呼叫,在 WSBase.as 中定義一個名為 call 的函式。這個函式使用 AsyncRequest 類傳送非同步請求,實現遠端過程呼叫。當遠端請求完成時,回撥請求中指定的響應器。還需要定義 processResult 函式(處理結果資料)和 faultResult 函式(處理錯誤),見清單 5。

    清單 5. 在 WSBase.as 中呼叫伺服器
    						
    private function processResult(result:Object,wrappedData:Object):void
    {		
        var body:Object = result.message.body;
        var stringResult:String = String(body);
        //    trace(stringResult);
        if(stringResult == null  || stringResult == "")
        	return;
        var bodyXML:XML = XML(body);
        // remove the namespaces from the returned xml
        var regex:RegExp = new RegExp("xmlns[^\"]*\"[^\"]*\"","gi");
        var regex2:RegExp = new RegExp("

  7. 在向遠端 Web 服務傳送請求之前,必須裝載並解析服務的 WSDL 檔案。為此,在 WSBase.as 中定義一個名為 parseWSDL 的函式(見清單 6),它通過 HTTP 請求獲取 WSDL 檔案,當成功地裝載檔案時傳送 Web 服務請求。

    清單 6. WSBase.as 中的 WSDL 裝載器
    						
    private function parseWSDL(wsdlURL:String,aysnCallParam:Object=null):void{
       if(wsdlURL != null){
       this._wsdlURL = wsdlURL;
       var wsdlLoader:HTTPService = new HTTPService();
       wsdlLoader.url = this._wsdlURL;
       wsdlLoader.resultFormat="object";
       wsdlLoader.addEventListener(ResultEvent.RESULT,initWebService);
       wsdlLoader.addEventListener(FaultEvent.FAULT,wsdlFaultHandler);
       wsdlLoader.send();
       var obj:Object = this;
    	 function initWebService(event:ResultEvent):void{
    		    var _wsdlObj:Object = event.result;
    		    obj._importLoc = _wsdlObj["definitions"]["import"].location;
    		    obj._importNS = _wsdlObj["definitions"]["import"].namespace;
    		    obj._endpointURI = _wsdlObj["definitions"]
    ["service"]["port"]["address"].location;
    		    obj._operationNS = new Namespace("ns",obj._importNS);
    		    obj._isWSDLLoaded = true;
    		    if(aysnCallParam != null){
    		    	obj.call(aysnCallParam.operation,aysnCallParam.operationBody,
    aysnCallParam.callback);
    		    }
    		}                
    	}
    }
    private function wsdlFaultHandler(event:FaultEvent):void
    {
    var detail:String = "Uunable To LoadWSDL "+event.currentTarget.url;		
        Alert.show(detail, "Error");	
    }
    

  8. 現在已經建立了一個簡單的 Web 服務代理,下面可以建立 BFMWebService.asHTMWebService.as 類來實現所需的 BFM 和 HTM API。這兩個類都以 WSBase 作為超類。
  9. BFMWebService.as 中,定義 queryProcessTemplatesstartProcess 函式,它們與過程互動,見清單 7。

    清單 7. BFMWebService.as 中的 BFMWebService 類
    						
    public class BFMWebService extends WSBase
    {
    	public function queryProcessTemplates(whereClause:String=null,
    orderByClause:String=null,threshold:Number=10,
    callback:Function=null):void{
              var out:Object = new Object();
              out["whereClause"] = whereClause;
              out["orderByClause"] = orderByClause;
              out["threshold"] = threshold;
      		    var soapOperation:String = "queryProcessTemplates";
      		    var operationBody:XML = ;
      		    var children:XMLList = this.objectToXML(out);
      		    operationBody.appendChild(children);
      		    this.aysnCall(soapOperation,operationBody,callback);
    	}
    	public function startProcess(processTemplateName:String,
    portTypeName:String,portTypeURI:String,
    operationName:String,operationInputs:IInputData,callback:Function=null):void{
              var param1:XML = {processTemplateName}
    ;
              var param2:XML = {portTypeName}
    
              var param3:XML = {operationName};
              var param4:XML = null;
              if(operationInputs != null){
              	param4 =  
              	param4.appendChild(operationInputs.toXML());
              	var inputNamespace:Namespace = new Namespace("tt",portTypeURI);
              	param4.setNamespace(inputNamespace);
              }
      		    var soapOperation:String = "sendMessage";
      		    var operationBody:XML = ;
      		    operationBody.appendChild(param1);
      		    operationBody.appendChild(param2);
      		    operationBody.appendChild(param3);
      		    if(param4 != null){
      		    	operationBody.appendChild(param4);
      		    }
      		    trace(operationBody);
      		    this.aysnCall(soapOperation,operationBody,callback);		
    	}
    }
    

  10. HTMWebService.as 中定義以下函式來操作人工任務:getTODOTasksclaimcompleteWithOutputtransferWorkItem,見清單 8。

    清單 8. HTMWebService.as 中的 HTMWebService 類
    						
    public class HTMWebService extends WSBase
    {
    	public function getTODOTasks(threshold:int,callback:Function=null):void{
              var out:Object = new Object();
              out["selectClause"] = "TASK.TKIID,TASK.NAME,TASK.ORIGINATOR,TASK.OWNER,
    TASK.STATE,TASK.KIND";
              out["whereClause"] = "(TASK.STATE = TASK.STATE.STATE_READY OR 
    TASK.STATE = TASK.STATE.STATE_CLAIMED) AND (TASK.KIND = 
    TASK.KIND.KIND_PARTICIPATING OR TASK.KIND = TASK.KIND.KIND_HUMAN) AND 
    WORK_ITEM.REASON = WORK_ITEM.REASON.REASON_POTENTIAL_OWNER";
              out["skipTuples"] = 1;
              out["threshold"] = threshold;
    	    var soapOperation:String = "query";
    	    var operationBody:XML = ;
    	    var children:XMLList = this.objectToXML(out);
    	    operationBody.appendChild(children);
    	    this.aysnCall(soapOperation,operationBody,callback);		    
    	}
    
    	public function claim(tkiid:String,callback:Function=null):void{
              var out:Object = new Object();
              out["tkiid"] = tkiid;
    	    var soapOperation:String = "claim";
    	    var operationBody:XML = ;
    	    var children:XMLList = this.objectToXML(out);
    	    operationBody.appendChild(children);
    	    this.aysnCall(soapOperation,operationBody,callback);		    
    	}
    	public function completeWithOutput(tkiid:String,taskServiceInterfaceURI:String,
    tResponse:IInputData,
    callback:Function=null):void{
    		var param1:XML = {tkiid};
    		if(tResponse != null){
                  var param2 = tResponse.toXML();
              	var inputNamespace:Namespace = new Namespace
    (taskServiceInterfaceURI);
              	param2.setNamespace(inputNamespace);				
    		   var soapOperation:String = "completeWithOutput";
    	       var operationBody:XML = ;
    	       operationBody.appendChild(param1);
    	       operationBody.appendChild(param2);
    	       trace(operationBody);
    	       this.aysnCall(soapOperation,operationBody,callback);
    		}
    	}
    
    	public function transferWorkItem(identifier:String,fromOwner:String,
    toOwner:String,
    callback:Function=null)
    :void{
              var out:Object = new Object();
              out["identifier"] = identifier;
              out["assignmentReason"] = 4;
              out["fromOwner"] = fromOwner;
              out["toOwner"] = toOwner;
    	    var soapOperation:String = "transferWorkItem";
    	    var operationBody:XML = ;
    	    var children:XMLList = this.objectToXML(out);
    	    operationBody.appendChild(children);
    	    this.aysnCall(soapOperation,operationBody,callback);			
    	}		
    }
                

用 Flex 建立使用者介面

現在已經建立了呼叫 BFM 和 HTM Web 服務 API 的類,下面建立一個簡單的使用者介面,它使用這些 API 與過程和人工任務互動。

在我們的示例中(見圖 17),您會看到:

  • 頂部有一個表單,它用於配置 Web 服務的引數。
  • 左邊有一個用於操作過程的皮膚,可以在其中檢視過程模板並建立新的訂購請求過程。
  • 右邊有一個用於操作人工任務的皮膚,可以在其中檢視人工任務、宣告、完成並傳輸工作項。


圖 17. 示例應用程式的簡單 UI
示例應用程式 UI

解壓 BizFlexClient.zip 的 Flex 專案原始碼目錄中的 BizFlexClient.mxml 檔案包含使用者介面的完整原始碼。可以把這個檔案複製到 Flex 專案 BizFlexClient 中以建立使用者介面。

我們來看看用來構建使用者介面的一些指令碼函式:

  1. 在 BizFlexClient.mxml 的 Script 部分中,更新 BFM 和 HTM Web 服務 WSDL 檔案 URL 的值,見清單 9。

    清單 9. 在 BizFlexClient.mxml 中更新 WSDL 檔案 URL 和使用者名稱的值
    						
    [Bindable]
    private var bfmws:BFMWebService = new BFMWebService(null);
    private var htmws:HTMWebService = new HTMWebService(null);            
    public function initWebService():void{
    	bfmws.setCredentials(this.userName.text,this.password.text);
    	bfmws.setWsdlURL(this.bfmws_url.text);
     	htmws.setCredentials(this.userName.text,this.password.text);
    	htmws.setWsdlURL(this.htmws_url.text);           	
    }  
    

  2. 對於每個按鈕,新增 click 屬性,讓應用程式知道當使用者單擊按鈕時應該做什麼,見清單 10。onQueryProcessTemplates ()onNewOrderProcess()onGetTODOTasks()onClaim()onComplete()onTransfer() 的基本邏輯是相似的;清單 10 給出 onQueryProcessTemplate

    清單 10. BizFlexClient.mxml 中的按鈕定義和相應的函式
    						
    
    
    
    
    
    
                

現在 Flex 客戶機應用程式已經完成了,它可以通過呼叫 BFM 和 HTM Web 服務 API 與 Process Server 上執行的 OrderSampleProcess 互動。可以輕鬆地擴充套件它以使用其他 BFM 和 HTM Web 服務 API,以及為其他業務流程應用程式構建相似的客戶機。

按以下步驟部署和執行示例:

  1. 確認 Process Server 已經啟動而且在 Process Server 上已經安裝了 OrderSampleProcess.ear,然後啟動應用程式。
  2. 在解壓 BizFlexClient.zip 的目錄中找到 BizFlexClient.html。
  3. 在瀏覽器中開啟 BizFlexClient.html。
  4. 在配置表單中(見圖 18),確認 BFM 和 HTM Web 服務的 URL 是正確的,指定使用者 ID 和密碼。
  5. 現在,可以通過 Flex Web 頁面訪問部署的過程和人工任務。


圖 18. 業務流程應用程式的示例 Flex 客戶機
業務流程應用程式的示例 Flex 客戶機

在本文中,您瞭解瞭如何使用 WebSphere Integration Developer V6.2 構建業務應用程式,以及如何在 Flex 中使用 WebSphere Process Server 提供的 Business Flow Manager 和 Human Task Manager Web 服務 API 與業務流程和人工任務互動。您現在應該能夠為 WebSphere 業務應用程式設計和開發與 Adobe Flex 相似的 Web 服務客戶機。

作者要感謝 Wu Yu、Xiang Cheng、Jia Gu 和 Yun Zhi Bian 為本文提供的幫助。

原文連結:http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1003_xue/1003_xue.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14789789/viewspace-674577/,如需轉載,請註明出處,否則將追究法律責任。

相關文章