表 6. 使用 JSP 實現的系統界面
|
名稱 |
訪問路徑 |
描述 |
|
approver.jsp |
/approver/approver.jsp |
頁面啟動時向後台 LoadApproveData 請求並展示需要審核的發票數據,並向 ApproverServlet 發送審核請求 |
|
basic_index.jsp |
/indexer/basic_index.jsp |
發票錄入員所示用的發票數據錄入頁面,向 DisposeIndexServlet 發送請求數據,其包含兩個標籤頁,區分待審核數據和基本的流程數據 |
|
index_list.jsp |
/indexer/index_list.jsp |
系統起始頁面,用於展示當前所有活動的流程實例的列表,通過向 LoadProcessListData 發送請求獲取數據 |
調用 WebAPI 必須包含的兩個主要的 Jar 包,其中 teamworks-client-sample.jar 是使用 WebAPI 的輔助類,可以在 IBM BPM 的安裝目錄下找到,其中的 lib 目錄下包含了使用該 Jar 包所依賴的其他的 Jar 包。webapi.jar 是連接 IBM BPM 的功能包,可以在服務端安裝目錄下直接找到。將所需包導入到工程的 Class Path 下。
新建一個普通 Java 類,命名為 WebAPIUtil,該類利用 teamworks-client-sample.jar 所提供的功能,產生 WebAPI 的實例,詳細代碼可查看示常式序程序中的 WebAPIUtil.java,下面是關鍵代碼:
|
WebAPIFactory factory = WebAPIFactory.newInstance(properties); // Create a new WebAPI client stub factory.setProperty(Stub.USERNAME_PROPERTY, username); factory.setProperty(Stub.PASSWORD_PROPERTY, password); webAPI = factory.newWebAPI();
|
上面這段代碼展示了通過 WebAPIFactory 產生 WebAPI 連接實例的過程,其中 username、password 用於連接 IBM BPM 的服務端,必須是合法的用戶名 / 密碼對,properties 對象通過 properties 配置文件產生,可參考示常式序中的 WebAPIFactory.properties 文件,內容如下:
清單 2. WebAPIFactory.properties 配置文件內容片段
|
Wjavax.xml.rpc.service.endpoint.address= http://[ibm-bpm-host]:[port]/webapi/services/WebAPIService javax.xml.rpc.session.maintain=true com.lombardisoftware.includeNullArrayElements=true
|
其中第一條配置信息包含了要訪問的 WSDL 文件的地址,[ibm-bpm-host]:[port] 分別是 IBM BPM 的伺服器地址和埠號。
新建一個 Servlet,取名為 LoadProcessListData,該程序創建一個查詢(Search),查詢出當前伺服器所有活動的流程實例,詳細代碼可查看示常式序中的 LoadProcessListData.java,關鍵代碼如下:
清單 3. LoadProcessListData.java 代碼片段
|
WwebAPI = WebAPIUtil.getWebAPIConnection(username, password,webAPIProperty); // execute query to get the process instance list SearchResultRow[] rrs = getActiveInstanceList(); // generate XML data String xmloutput = getXMLDataFromSearch(rrs);
|
其中第一行代碼展示了通過先前創建的輔助工具類獲取 WebAPI 的實例,第三個參數為配置文件所在的路徑。第二行代碼通過調用一個方法獲取查詢的結果了數組,最後通過該數組生成需要返回的 XML 字元串,其中獲取查詢結果的代碼如下:
|
Search se = new Search(); se.setOrganizedByType(“ProcessInstance”); SearchResults sr = null;
// set search column for the search and search result SearchColumn searchColumn1 = new SearchColumn(); searchColumn1.setType(“ProcessInstance”); searchColumn1.setName(SearchableProcessInstanceColumn._Id); SearchColumn searchColumn2 = new SearchColumn(); searchColumn2.setType(“ProcessInstance”); searchColumn2.setName(SearchableProcessInstanceColumn._Name);
// set the condition SearchColumn searchColumn3 = new SearchColumn(); searchColumn3.setType(“ProcessInstance”); searchColumn3.setName(SearchableProcessInstanceColumn._Status); SearchCondition searchCondition1 = new SearchCondition(); searchCondition1.setColumn(searchColumn3); searchCondition1.setOperator(“EQUALS”); searchCondition1.setValue(“Active”);
// create data SearchColumn[] scs = new SearchColumn[2]; scs[0] = searchColumn1; scs[1] = searchColumn2; SearchCondition[] sCond = new SearchCondition[1]; sCond[0] = searchCondition1;
// do the search se.setColumns(scs); se.setConditions(sCond); try { sr = webAPI.executeSearch(se, null, null); } catch (RemoteException e) { e.printStackTrace(); } return sr.getRows();
|
此段代碼先創建一個 Search 對象,然後將結果的組織類型設置為根據”ProcessInstance”的方式,及以 Process 實例為基本單位獲取結果,5 至 10 行創建需要展示的結果的列,12 至 18 行創建需要查詢的條件,20 至 24 行設置查詢數據,最後調用 WebAPI 的方法執行查詢並返回結果。
當然,調用 Search 的方式除了上面介紹的通過代碼硬編碼的方式以外,還可以通過 IBM BPM 的 Portal 創建 Saved Search,然後通過 WebAPI 直接調用,類似於調用資料庫中的存儲過程。
此時通過界面即可查看當前的活動的實例列表,界面詳細代碼可查看示常式序中 index_list.jsp 及 process_instance_list.js 文件。
新建一個 Servlet,命名為 DisposeIndexServlet,該 Servlet 會接受頁面參數,將參數通過”COCE_GIW_ALL_Index”活動傳入到流程中,並將流程從當前活動推動到下一個指定的活動節點上,詳細代碼可查看示常式序中的 DisposeIndexServlet.java,下面是關鍵代碼:
清單 5. DisposeIndexServlet.java 代碼片段
|
int variableLength = 5; // variable length need to // initialize the varaibles Variable[] vars = new Variable[variableLength]; for(int i=0; i<vars.length; i++){ vars[i] = new Variable(); } vars[0].setName(“maxNumberApprovers”); vars[0].setValue(numApprs); try { vars[1] = makeApproverName(approvers); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } vars[2].setName(“duplicateCheck”); vars[2].setValue(duplicateCheck); …… vars[3] = makeContentList(contents);
// dispose the complex value ComplexValue cv = (ComplexValue)vars[3].getValue(); MessageElement arrayOfStr = cv.get_any()[0].getRealElement(); if(null != arrayOfString){ List<MessageElement> elementList = arrayOfStr.getChildren(); for(MessageElement strEle : stringElementList){ Text e = (Text) strEle.getChildren().get(0); e.setValue(mailContent); } } vars[4] = makeInvoiceData(data);
|
如上所示,程序首先創建 Variable 類型的數組,程序通過該數組給 Process 實例傳遞參數,對於簡單參數,只需要調用 Variable 對象的 setName 和 setValue 為設置名稱和對應的值,名稱必須和活動中的參數名稱相同。代碼中 vars[1]、vars[3] 和 vars[4] 比較特殊,因為他們都是複雜類型的數據,類似於 C/C++ 中的結構體,需要通過反序列化的方式,其中 vars[1] 對應了流程定義中的參數 approverNames,它是一個 String 的列表類型,但是不同於 Java 的 String[] 或是 List<String> 及其子類型 , 後面會有詳細的介紹,vars[3] 對應了 BPD 中的 mailContents 參數,也是 String 列表類型,vars[4] 對應了 BPD 中的 InvoiceDataModel 類型,同樣是複雜類型的數據結構,下面以 InvoiceDataModel 為例,介紹一下 makeInvoiceData 方法中的序列化代碼,如下:
|
Variable v = null; StringBuffer outputXml = new StringBuffer(“<InvoiceDataModel xmlns=\”http://www.w3.org/2001/XMLSchema\”>”); outputXml.append(“<Source>” + data.source + “</Source>>”); outputXml.append(“<UserID>” + data.userid + “</UserID>”); outputXml.append(“<Timestamp>” + data.Timestamp + “</Timestamp>”); outputXml.append(“<D_DocStatus>” + data.d_DocStatus + “</D_DocStatus>”); outputXml.append(“<ORIGIN_ITEM_ID>” + data.origin_item_id + “</ORIGIN_ITEM_ID>”); outputXml.append(“<OLD_CREATETS>” + data.old_creates + “</OLD_CREATETS>”); outputXml.append(“</InvoiceDataModel>”); // create variable v = new Variable(“invoiceData”, ClientUtilities.toComplexValue(outputXml.toString())); return v;
|
在構建流程定義的過程中,我們創建了複雜的數據類型 InvoiceDataModel,圖 26 展示了該數據類型的 Schema 定義,上面的代碼即根據該 Schame 的定義構建複雜數據類型的結構,最後通過 ClientUtilities 將 XML 轉換成一個
以下文章點擊率最高
Loading…