5
BPM工作流workflow
你的位置:首頁->解決方案

F2BPM流程中心RESTfull解決方案

發布時間:2018-11-21  來源:F2BPM所屬公司:廣州致博軟件科技有限公司    閱讀量:8808

 引言

1.1. 應用背景

隨時企業的IT系統建設越來越多,往往一個企業中形成各種獨立的系統,各系統相對獨立,缺乏流程支掌,為達到通過構建流程服務中心向各處應用系統提供流程服務,同時將各個獨立的系統以流程中心為扭帶鏈接起來。

流程中心僅是作為后臺管理,對于用戶來說并不需要登錄此平臺上做相關的業務操作管理。流程中心作為應用系統的服務端,應用系統作為客戶端。流程中心相對前端的客戶來說是一個黑盒模式。

F2BPM流程服務中心(簡稱:F2流程中心),是指將F2-BPM做為流程平臺獨立部署成流程中心的方式,其它應用系統調用F2流程服務中心進行流程流轉的使用場景。

由于每個企業自身的IT系統應用環境千差萬別,本文檔給出F2流程中心應用到企業中作為流程中心的常見應用解決方案。

目前越來越多的企業架構解決方案更加趨向于基于http協議“微服務”架構,即通過RESTfull方式進行交互,更加輕量整合調用更上方便。F2流程中心應用方案也是建議采用輕量級的RESTfull方案。

1應用方案模式

由于企業的IT建設的環境不心相同,構建流程中心的方案也會有所不同,由于獨立部署面臨的一個最大問題就:用戶組織架構問題、登錄授權身份問題。所以會有不同的企業IT環境會有不同的應用方案模式。

  • 方案模式一:流程中心和應用系統共同相同數據庫,程序獨立部署方式
  • 方案模式二:流程中心和應用系統的數據庫和程序都是獨立部署方式
  • 方案模式三:有統一人事系統用戶認證服務器,流程中心和應用系統的數據庫和程序都是獨立部署

 

2. 共用數據庫模式

 

 

共用數據庫模式是指流程中心與應用系統使用相同的數據,將流程中心的所有表建包括流程中心平臺用戶組織表都創建在應用系統所在的數據庫中。

此時流程中心的用戶組織架構管理僅是作為流程中心平臺管理員使用的用戶組織,用于登錄維護管理流程中心相關的事務。流程中心的用戶組織與應用系統的用戶組織無關。而當調用流程中心執行流程流轉時用戶組織是通過引擎的用戶組織架構接入的配置讀取應用系統的用戶組織,依然使用的是應用系統自身的用戶組織架構。流程引擎使用的是應用系統自身的用戶組織架構,用戶組織架構的維護管理依然是由應用系統自身來管理。

RESTfull的數據交互機制詳細見Oauth2.0接口交互授權。

 

3. 獨立程序和數據庫部署模式

 

數據庫和程序都是獨立部署模式是指流程中心與應用系統使用各自的數據庫。

此時流程中心自身數據庫中的用戶組織架構管理僅是作為流程中心平臺管理員使用的用戶組織,用于登錄維護管理流程中心相關的事務。流程中心的用戶組織與應用系統的用戶組織無關。

而當調用流程中心執行流程流轉時用戶組織是通過重寫F2用戶組織架構接口的實現讀取應用系統的用戶組織架構,依然使用的是應用系統自身的用戶組織架構。流程引擎使用的是重寫實現組織接口的應用系統自身的用戶組織架構,用戶組織架構的維護管理依然是由應用系統自身來管理。

 

 

 

 

 

 

4. 使用統一人事系統用戶服務器模式

 

 

 

使用統一人事用戶系統模式是最復雜但也是整體企業信息化環境比較好的方式,一般應用于比較大的集團企業,他們的特點是數據庫和程序都是獨立部署,流程中心與應用系統使用各自的數據庫,同時各應用系統都是統一使用HR系統的用戶組織架構。

此時流程中心自身數據庫中的用戶組織架構管理僅是作為流程中心平臺管理員使用的用戶組織,用于登錄維護管理流程中心相關的事務。流程中心的用戶組織與應用系統的用戶組織無關。

而當調用流程中心執行流程流轉時用戶組織是通過重寫F2用戶組織架構接口的實現讀取應用系統的用戶組織架構,依然使用的是應用系統自身的用戶組織架構。流程引擎使用的是重寫實現組織接口的應用系統自身的用戶組織架構,用戶組織架構的維護管理依然是由應用系統自身來管理。

因企業信息化環境差異大,此方案需要各方一同共同實施才能達到比較好的效果。我們可以合作實施。

5. RESTfull接口的OAuth2.0身份授權

5.1. 什么是OAuth2.0

OAuth2.0是一個關于授權(authorization)的開放網絡標準,在全世界得到廣泛應用,目前的版本是2.0版。本文是對OAuth 2.0的設計思路和運行原理應用到F2BPM平臺中,目標是為了防止接口被不安全使用,接口的調用必須有安全的身份認證機制。

5.2. OAuth2.0與F2-BPM平臺

因為要將F2-BPM平臺做為流程服務中心,那么F2-BPM平臺就會與多個應用系統打交道,多個應該系統通過調用RESTfull接口來驅動流程或者獲取流程相關數據時需要安全驗證后才可以進行接口影響返回正確的數據結果。

F2-BPM流程中心構建了OAuth2.0的身份認證機制,此身份的認證是應該系統級別的,目的驗證是否來自合法注冊的應該系統調用了流程中心的RESTfull接口。(數據關聯的用戶是應用系統開發調用流程中心接口時決定)。

本流程中心的OAuthor并非用于用戶的第三方登錄認證,當然也能擴展出來,但由于F2-BPM并非人事系統的統一用戶管理中心。

5.3. F2-BPM流程中心OAUTH2.0身份驗證時序圖

 

每個接口必須傳遞的數據:{token:,corpId:,timeStamp:,nonce:,signature:,loginAccount:}

參數名

值示例

說明

token

oa_token

系統令牌,在流程中心配置的固定值

corpId

app255e7feb2645dd23

應用系統的ID,在流程中心增加應用接入時生成的ID

timeStamp

1706261844

時間戳,傳遞時由客戶端生成,格式:yymmddHHmm,客戶端時間與F2-PBM流程中心系統時間誤差充許在10分鐘以內

nonce

6723

隨時數,由客戶端生成一個至少4位的隨時數

signature

ZDlUMYZeJKXrAZ3ofbZQnXgSPqjHw9xw2lZhj0hPwF5VUG0yMhknJ-8Ql8zK8tXK

簽名加密字符串,由客戶端將timeStamp和nonce進行加密得到此簽名加密字符串

loginAccount

zs

當前登錄者的賬號,用于作為調用RESTfull接口流程引擎將以此賬號作為流程引擎運行中的當前登錄人身份

 

客戶端與流程中心接口交互參數說明:

authorJson:主要是接口身份的認證相關參數,校驗訪問者的來源合法性


parmJson:請求業務數據的參數,比如分頁參數,查詢參數等 所有RESTfull都統一只有這兩個Json參數 一般情況

 

get只適合參數相對簡單的請求,如果參數過長或參數字符復雜,則使用Post 來傳參請求。

 

F2BPM接口強大的特點:服務端可以利用F2BPM非常豐富的流程引擎WAPI進行發布成RESTfull服務接口供應用端系統調用。而且接口可以是無狀態的請求

客戶端Get請求  

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
     * get請求 get只適合參數相對簡單的請求,如果參數過長或參數字符復雜,則使用Post 來傳參請求
     */
    public void getTodoList() {
        String urlString = webApiUrl + "/workflowBusiness/getTodoList/?";
        StringBuilder queryString = new StringBuilder();
        queryString.append(StringUtil.format("authorJson={loginAccount:\"{0}\"}""admin"));
        queryString.append(StringUtil.format("&parmJson={pageIndex:{0},pageSize:{1},sort:\"{2}\",order:\"{3}\"}"12"CreatedTime""desc"));
        String param = HttpClientUtil.urlEncode(queryString.toString()); // 特殊字符進行轉義
        urlString = urlString + param;
        String jsonRes = HttpClientUtil.get(urlString);
        System.out.println(jsonRes);
    } 

對應的流程中心服務端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 獲取待辦列表
    @RequestMapping(value = "getTodoList", method = RequestMethod.GET)
    public void getTodoList(String authorJson, String parmJson, HttpServletRequest request, HttpServletResponse response) throws Exception {
        JSONObject jsonJSONObject = JSONObject.fromObject(parmJson);
        PageParams pageParams = JsonHelper.jsonToObject(parmJson, PageParams.class);
        AuthorEntity authorEntity = JsonHelper.jsonToObject(authorJson, AuthorEntity.class);
        String loginAccount = authorEntity.getLoginAccount();
        MyInteger recordCount = new MyInteger(0);
        MyInteger pageCount = new MyInteger(0);
        String whereStr = JsonHelper.getString(jsonJSONObject, "whereStr");
        IUser user = userService.getUserByAccount(loginAccount);
        List<TaskInstanceInfo> list = WorkflowAPI.getWorkTaskManager().getTodoList(user.getUserId(), whereStr.toString(), pageParams.getOrderBy(), pageParams.getPageIndex(), pageParams.getPageSize(), pageCount, recordCount, true);
        String jsonString = JsonHelper.listToJSON(list);
        String jsonResult = JsonHelper.convertToEasyUIJsonResult(jsonString, pageParams.getPageSize(), pageParams.getPageIndex(), recordCount.getValue(), pageCount.getValue());
        JsonHelper.write(response, jsonResult);
    }

 

Post請求來獲取已辦列表

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * post請求,參數復雜的建議使用Post來請求
 */
public void getDoneList() {
    String urlString = webApiUrl + "/workflowBusiness/getDoneList/";
    Map<String, String> params = new HashMap<String, String>();
    StringBuilder queryString = new StringBuilder();
    params.put("authorJson", StringUtil.format("{loginAccount:\"{0}\"}""admin"));
    // isHistory:0 進行中的已辦,isHistory:1流程已結束并歸檔的已辦
    params.put("parmJson", StringUtil.format("{isHistory:0,pageIndex:{0},pageSize:{1},sort:\"{2}\",order:\"{3}\",whereStr:\"{4}\",}"12"CreatedTime""desc"""));
    String jsonRes = HttpClientUtil.post(urlString, params);
    System.out.println(jsonRes);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 流程中心服務-已辦列表
    @RequestMapping(value = "getDoneList", method = RequestMethod.POST)
    public void getDoneList(String authorJson, String parmJson, HttpServletRequest request, HttpServletResponse response) throws Exception {
        JSONObject jsonJSONObject = JSONObject.fromObject(parmJson);
        PageParams pageParams = JsonHelper.jsonToObject(parmJson, PageParams.class);
        AuthorEntity authorEntity = JsonHelper.jsonToObject(authorJson, AuthorEntity.class);
        String loginAccount = authorEntity.getLoginAccount();
        MyInteger recordCount = new MyInteger(0);
        MyInteger pageCount = new MyInteger(0);
        String whereStr = JsonHelper.getString(jsonJSONObject, "whereStr");
        int isHistory = JsonHelper.getInt(jsonJSONObject, "isHistory");
        IUser user = userService.getUserByAccount(loginAccount);
        List<TaskInstanceInfo> list =null;
        if(isHistory==1){
            //歸檔中的列表
              list = WorkflowAPI.getHistoryDataManager().getHistoryDoneList(user.getUserId(), whereStr.toString(), pageParams.getOrderBy(), pageParams.getPageIndex(), pageParams.getPageSize(), pageCount, recordCount, true);
        }else {
            //進行中的已辦
             list = WorkflowAPI.getWorkTaskManager().getDoneList(user.getUserId(), whereStr.toString(), pageParams.getOrderBy(), pageParams.getPageIndex(), pageParams.getPageSize(), pageCount, recordCount, true);
        }
         
        String jsonString = JsonHelper.listToJSON(list);
        String jsonResult = JsonHelper.convertToEasyUIJsonResult(jsonString, pageParams.getPageSize(), pageParams.getPageIndex(), recordCount.getValue(), pageCount.getValue());
        JsonHelper.write(response, jsonResult);
    }
    

 輸出響應結果到客戶端

復制代碼
{"success":true,"msg":"","total":4,"pageCount":2,"pageSize":2,"pageIndex":1, "rows":[{"isDelegateDone":false,"workflowTitle":"[系統管理員費用報銷申請","directBackAct":"","expectFinishedTime":
{"time":0,"minutes":0,"seconds":0,"hours":8,"month":0,"year":70,"timezoneOffset":-480,"day":4,"date":1},"businessKey":"","delegatorUserId":"","respondType":"","delegatorRealName":"",
"wiState":0,"taskExpireTime":null,"mainActivityInstanceId":"","urgency":1,"activityId":"","extStr":"","formId":"bdd11478-97ab-4612-beb9-575a3b3d9e83","description":"","userId":"3c1df0b3-a4d9-4731-b143-02e81bce17ce",
"delegatorName":"","userName":"","opinion":"","taskDealHours":0,"appType":"表單規則2.0","isCirculated":false,"isContainDelegator":false,"currentActors":"","fromCreatorID":"","taskCreateType":"","currentActivityName":"",
"openBizDate":"","isReferred":false,"delegatorMobile":"","importance":1,"workflowInstanceState":2,"activityShowName":"","userMobile":"","creatorRealName":"系統管理員","userDpId":"","taskState":0,"isValid":false,"userDpName":"",
"appId":"AI","formType":"","workflowInstanceId":"5e2cfc5b-3fcb-4ae5-ae1d-fbdb27b4980e","creatorDepartId":"ZhiBoRuanJian","fromTaskId":"","activityInstanceId":"","taskSeq":"","creator":"admin","realTime":null,
"isCompleter":false,"completedType":"","delegatorDpName":"","finishedTime":null,"isMobileApproval":true,"stepId":0,"delegatorDpId":"","isMobileStart":true,"taskId":"","requirement":"",
"createdTime":{"time":1499268876000,"minutes":34,"seconds":36,"hours":23,"month":6,"year":117,"timezoneOffset":-480,"day":3,"date":5},"logs":"","creatorId":"3c1df0b3-a4d9-4731-b143-02e81bce17ce",
"taskRemark":"","secrecy":0,"commentCount":0,"mainWorkflowInstanceId":"","appName":"費用報銷申請","sheetId":"AI20170705233435818","completedTime":null,"isDelegatorCompleted":false,"workflowId":"3944ea6b-0c56-4c74-8b0e-af82d128f772",
"urgeTimes":0,"creatorDpName":"致博軟件","fromCreator":"","realName":"","activityName":"","startedTime":{"time":1499268876000,"minutes":34,"seconds":36,"hours":23,"month":6,"year":117,
"timezoneOffset":-480,"day":3,"date":5}},{"isDelegateDone":false,"workflowTitle":"系統管理員請假申請","directBackAct":"","expectFinishedTime":{"time":0,"minutes":0,"seconds":0,"hours":8,"month":0,"year":70,"timezoneOffset":-480,"day":4,"date":1},"businessKey":"","delegatorUserId":"","respondType":"","delegatorRealName":"",
"wiState":0,"taskExpireTime":null,"mainActivityInstanceId":"","urgency":1,"activityId":"","extStr":"","formId":"26eaad7d-ccfb-4b6a-96c0-4efc796f5d47","description":"","userId":"3c1df0b3-a4d9-4731-b143-02e81bce17ce","delegatorName":"","userName":"","opinion":"","taskDealHours":0,"appType":"表單規則2.0","isCirculated":false,"isContainDelegator":false,"currentActors":"","fromCreatorID":"","taskCreateType":"","currentActivityName":"","openBizDate":"","isReferred":false,"delegatorMobile":"","importance":1,"workflowInstanceState":2,"activityShowName":"","userMobile":"",
"creatorRealName":"系統管理員","userDpId":"","taskState":0,"isValid":false,"userDpName":"",
"appId":"AB","formType":"","workflowInstanceId":"a4d02561-7dc0-4a01-9368-687363081395","creatorDepartId":"ZhiBoRuanJian","fromTaskId":"",
"activityInstanceId":"","taskSeq":"","creator":"admin","realTime":null,"isCompleter":false,"completedType":"","delegatorDpName":"","finishedTime":null,"isMobileApproval":true,"stepId":0,"delegatorDpId":"","isMobileStart":true,"taskId":"","requirement":"","createdTime":{"time":1499268669000,"minutes":31,"seconds":9,"hours":23,"month":6,"year":117,"timezoneOffset":-480,"day":3,"date":5},"logs":"","creatorId":"3c1df0b3-a4d9-4731-b143-02e81bce17ce","taskRemark":"","secrecy":0,"commentCount":0,"mainWorkflowInstanceId":"",
"appName":"請假申請","sheetId":"AB20170705233109293","completedTime":null,"isDelegatorCompleted":false,
"workflowId":"4ae848a4-70f7-4e76-bd35-8f33f5bbac1e","urgeTimes":0,"creatorDpName":"致博軟件","fromCreator":"","realName":"","activityName":"",
"startedTime":{"time":1499268669000,"minutes":31,"seconds":9,"hours":23,"month":6,"year":117,"timezoneOffset":-480,"day":3,"date":5}}]}
復制代碼

 

發起流程示例:

客戶端

復制代碼
/**
     * post請求     */
    public void startWorkflow() {
        String urlString = webApiUrl + "/workflowBusiness/startWorkflow/";
        Map<String, String> params = new HashMap<String, String>();
        StringBuilder queryString = new StringBuilder();
        String onlineFormData = StringUtil.format("[{\"mainTable\":\"csb\",\"data\":[{\"name\":\"csb.nl\",\"value\":\"22\"},{\"name\":\"csb.MyId\",\"value\":\"\"},{\"name\":\"csb.zz\",\"value\":\"RestFull測試\"},{\"name\":\"csb.xm\",\"value\":\"RestFull姓名\"}],\"subTables\":[]}]");
        params.put("authorJson", StringUtil.format("{loginAccount:\"{0}\"}", "admin"));
        params.put("parmJson", StringUtil.format("{appId:\"{0}\",wiid:\"{1}\",businessKey:\"{2}\",title:\"{3}\",opinion:\"{4}\",jsonFormData:{5}}", "ZX", Guid.getGuid(), Guid.getGuid(), "應用端RestFull請求測試", "同意", onlineFormData));        // String param = HttpClientUtil.urlEncode(queryString.toString());        // //特殊字符進行轉義
        String jsonRes = HttpClientUtil.post(urlString, params);
        System.out.println(jsonRes);
    }
復制代碼

 

流程中心處理發起請求

復制代碼
    //響應發起流程
    @RequestMapping(value = "startWorkflow", method = RequestMethod.POST)    public void startWorkflow(String authorJson, String parmJson, HttpServletRequest request, HttpServletResponse response) throws IOException {
        JSONObject jsonJSONObject = JSONObject.fromObject(parmJson);
        AuthorEntity authorEntity = JsonHelper.jsonToObject(authorJson, AuthorEntity.class);
        String loginAccount = authorEntity.getLoginAccount();        // IUser user = userService.getUserByAccount(loginAccount);
        String appId = JsonHelper.getString(jsonJSONObject, "appId");
        String wiid = JsonHelper.getString(jsonJSONObject, "wiid");
        String businessKey = JsonHelper.getString(jsonJSONObject, "businessKey");
        String title = JsonHelper.getString(jsonJSONObject, "title");
        String opinion = JsonHelper.getString(jsonJSONObject, "opinion");
        String jsonFormData = JsonHelper.getString(jsonJSONObject, "jsonFormData");
        StringBuilder message = new StringBuilder();        boolean success = WorkflowAPI.getWorkflowEnactmentManager().startWorkflow(appId, wiid, businessKey, title, opinion, loginAccount, null, message, jsonFormData, null, 0, 0);
        String jsonResult = JsonHelper.outResult(success, message.toString());
        JsonHelper.write(response, jsonResult);
    }


點擊體驗平臺: F2BPM體驗平臺

 

關注BPM行業門戶公眾號,第一時間獲取最新BPM行業資訊。

注:如果本文章涉及版權或其他原因,請聯系我們刪除。

福彩3d号码424前后