深入理解Activiti工作流

Activiti作爲一個流行的開源工作流引擎,正在不斷髮展,其6.0版本以API形式提供服務,而之前版本基本都是要求我們的應用以JDK方式與其交互,只能將其攜帶到我們的應用中,而API方式則可以服務器獨立運行方式,能夠形成一個專網內工作流引擎資源共享的方式。而6.0之後去掉了PVM整個類。

Activiti執行的BPMN2.0,這個規範中有幾個要素見下圖:

其實最經常使用的是開始結束事件和任務,本文就以這三個爲例,說明通過UI畫圖和REST API方式如何實現調用,當然如果能夠了解BPMN的XML,就能更加精確地定製流程,否則只能是玩玩而已,當然如果你說掌握XML定義不如編程呢,至少編程工具還能提示錯誤,BPMN繪圖畫錯了很難發現,特別是攜帶很多數據,這些數據又有不同的邏輯關係時,隱藏在圖形化流程背後的邏輯關係被弱化了。

 

2.下載

我們可以從Activiti網站本身下載兩個webapps 的war文件。

對於v6.0.0,我們可以下載activiti-6.0.0.zip,解壓縮,war文件可以在activiti-6.0.0 / wars目錄中找到。

activiti-app提供了一個用戶界面,用戶可以通過該界面執行任何身份管理和任務管理相關的操作,創建用戶和組。同樣,activiti-rest是一個webapp,它提供REST API,用於對流程,任務等執行任何操

3. Activiti Kickstart App

我們需要一個可用的Java運行時和一個Apache Tomcat安裝來部署該應用程序。任何Web容器都可以工作,但Activiti主要在Tomcat上進行測試。

現在,我們只需要在Tomcat上部署戰爭並使用http:// localhost:8080 / activiti-app訪問它。

用戶名和密碼:

activiti-admin: admin/admin
activiti-app: admin/test
activiti-rest: kermit/kermit

主頁應如下所示:

 

 

3.1 數據庫

默認情況下,它使用H2內存數據庫。如果我們想要更改數據庫配置,我們可以檢查代碼並修改activiti-app.properties文件。執行此操作後,我們需要重新生成war文件,這可以通過運行start.sh腳本來完成。這將構建activiti-app以及所需的依賴項。

3.2。Kickstart App

當我們點擊Kickstart App時,我們會獲得使用Process的選項我們可以創建/導入流程並從這裏運行它們。

讓我們創建一個包含單個User Task的小流程,該任務接收來自用戶的消息。進入Kickstart應用程序後,要創建流程,請選擇Processes選項卡,然後單擊Create Process

流程編輯器將打開,我們可以拖放開始事件,各種類型的任務和結束事件的各種符號來定義流程。

當我們在我們的流程中添加用戶任務時,我們需要將其分配給某人。我們可以通過單擊此任務選項中的分配並選擇受理人來完成此操作

爲簡單起見,讓我們將任務分配給流程啓動器:

我們還希望此用戶任務從用戶獲取輸入消息。爲此,我們需要將Form與單個文本字段關聯到此任務。

選擇用戶任務,然後選擇參考表格 Referenced form。目前,沒有與任務關聯的表單,因此單擊“ 新建表單”,然後添加所需的詳細信息:

在此之後,它將帶我們到表單部分,我們可以在表單中拖放我們想要的各種字段,併爲它們設置標籤:

請注意,我們已勾選Required,這意味着如果不輸入Message,則無法完成User任務

完成後,我們將保存並轉到“app標籤。爲了能夠運行我們創建的流程,我們需要創建一個Process App。

在Process App中,我們可以添加一個或多個Process Definitions。執行此操作後,我們需要發佈此應用程序,以便其他用戶可以使用流程,這個發佈很重要,如果你的流程有錯誤就發佈不了,當然Activiti也不會像IDE那樣告訴你精確的錯誤位置和原因或提示,你自己好好反省自查。

當然我們也可以將流程導出BPMN.xml文件,主要部分內容:

<startEvent id="startEvent1"></startEvent>
<userTask id="sid-9A9219F8-306C-4ED0-A243-88756537F7FA" activiti:assignee="$INITIATOR" activiti:formKey="userinputmessage">
<extensionElements>
<modeler:activiti-idm-initiator xmlns:modeler="http://activiti.com/modeler"><![CDATA[true]]></modeler:activiti-idm-initiator>
</extensionElements>
</userTask>
<sequenceFlow id="sid-4CB3BA7F-30A3-49F6-97CE-82D0BD2FD9F8" sourceRef="startEvent1" targetRef="sid-9A9219F8-306C-4ED0-A243-88756537F7FA"></sequenceFlow>
<endEvent id="sid-A6BA7A4E-D1AC-451D-A3D2-5FEC5408519C"></endEvent>
<sequenceFlow id="sid-B8CC1746-E80B-4185-AA6A-5E85031E4152" sourceRef="sid-9A9219F8-306C-4ED0-A243-88756537F7FA" targetRef="sid-A6BA7A4E-D1AC-451D-A3D2-5FEC5408519C"></sequenceFlow>
</process>

這些startEvent、userTask是文章開頭第一張圖裏面的對應含義。sequenceFLow是順序流,startEvent是流程事件,userTask是任務。

 

3.3 任務應用程序

在任務應用程序中,有兩個選項卡:任務 - 用於當前正在運行的任務,以及流程 - 用於當前正在運行的流程。

單擊“ 流程中的開始流程”選項卡後,我們將獲得可以運行的可用流程列表。從此列表中,我們將選擇我們的流程並單擊開始按鈕,只有你的流程發佈publish之後才能看到,也才能按開始按鈕。

我們的流程只包含一個任務,它是一個用戶任務。因此,該過程正在等待用戶完成此任務。當我們點擊流程正在等待的任務時,我們可以看到我們創建的表單:

如果我們點擊查看圖,這將不僅向我們展示過程圖也強調,完成的任務和正在等待的人。在我們的示例中,用戶任務仍處於待處理狀態,會突出顯示:

要完成此任務,我們可以單擊Complete butto n。如前所述,我們需要輸入消息,因爲我們必須保留它。因此,在輸入消息後,我們可以完成任務。

3.4。身份管理應用

除了管理流程外,我們還有一個身份管理應用程序,允許我們添加用戶和組。我們還可以爲用戶定義角色。

4. Activiti REST

Activiti爲Activiti Engine提供REST API,可以通過將activiti-rest.war文件部署到像Apache Tomcat這樣的servlet容器來安裝。

默認情況下,Activiti Engine將連接到內存中的H2數據庫。就像我們在activiti-app中看到的一樣,在這裏我們可以更改WEB-INF / classes文件夾中db.properties文件中的數據庫設置並重新創建war文件。

啓動並運行應用程序後,我們可以將此基本URL用於所有請求:

http://localhost:8080/activiti-rest/service/

默認情況下,所有REST資源都需要對有效的Activiti用戶進行身份驗證。每次REST調用都應使用基本HTTP訪問身份驗證。

4.1。創建和運行流程

要創建流程,首先,我們需要BPMN文件用於流程。我們可以按照之前基於Activiti with Java的文章中的描述創建文件,也可以從Kickstart App的Process部分下載。

我們需要發一個POST請求,以及contentType:multipart / form-data,我們將爲我們的新流程上傳BPMN文件,在postman中設置:body中選擇form,key填入file;類型從text和file中選擇file,然後上傳我們之前導出的BPMN.xml文件,授權選擇basic auth,用戶名和密碼: kermit

POST http://127.0.0.1:8080/activiti-rest/service/repository/deployments

當我們通過傳遞我們創建的流程的BPMN文件來進行此調用時,它將提供以下輸出:

{
"id": "40",
"name": "myprocess.bpmn20.xml",
"deploymentTime": "2018-08-21T15:20:11.056+08:00",
"category": null,
"url": "http://127.0.0.1:8080/activiti-rest/service/repository/deployments/40",
"tenantId": ""
}

現在,如果我們獲得所有流程定義,我們可以看到列出的流程定義:

 

GET http://127.0.0.1:8080/activiti-rest/service/repository/process-definitions

接下來,我們可以使用我們在BPMN文件中提到的processKey來運行此過程:

POST http://127.0.0.1:8080/activiti-rest/service/runtime/process-instances

有了這個請求正文:

{
"processDefinitionKey":"myprocess-Id"
}

響應將是:

{
"id": "48",
"url": "http://127.0.0.1:8080/activiti-rest/service/runtime/process-instances/48",
"businessKey": null,
"suspended": false,
"ended": false,
"processDefinitionId": "myprocess-Id:2:47",
"processDefinitionUrl": "http://127.0.0.1:8080/activiti-rest/service/repository/process-definitions/myprocess-Id:2:47",
"processDefinitionKey": "myprocess-Id",
"activityId": null,
"variables": [],
"tenantId": "",
"name": null,
"completed": false
}

我們可以使用上一個響應返回的流程實例的id來查看正在運行的流程圖:

 

GET http://127.0.0.1:8080/activiti-rest/service/runtime/process-instances/48/diagram

如前所述,該過程正在等待用戶任務完成,因此它在圖中突出顯示:

 

4.2。完成任務

現在讓我們看看我們的待處理任務:

 

GET http://127.0.0.1:8080/activiti-rest/service/runtime/tasks

響應將包含待處理任務的列表。目前,只有一項任務 - 我們的用戶任務

{
      "data": [
      {
      "id": "53",
      "url": "http://127.0.0.1:8080/activiti-rest/service/runtime/tasks/53",
      "owner": null,
      "assignee": "$INITIATOR",
      "delegationState": null,
      "name": null,
      "description": null,
      "createTime": "2018-08-21T15:23:55.714+08:00",
      "dueDate": null,
      "priority": 50,
      "suspended": false,
      "taskDefinitionKey": "sid-9A9219F8-306C-4ED0-A243-88756537F7FA",
      "tenantId": "",
      "category": null,
      "formKey": "userinputmessage",
      "parentTaskId": null,
      "parentTaskUrl": null,
      "executionId": "50",
      "executionUrl": "http://127.0.0.1:8080/activiti-rest/service/runtime/executions/50",
      "processInstanceId": "48",
      "processInstanceUrl": "http://127.0.0.1:8080/activiti-rest/service/runtime/process-instances/48",
      "processDefinitionId": "myprocess-Id:2:47",
      "processDefinitionUrl": "http://127.0.0.1:8080/activiti-rest/service/repository/process-definitions/myprocess-Id:2:47",
      "variables": []
      }
      ],
      "total": 1,
      "start": 0,
      "sort": "id",
      "order": "asc",
      "size": 1
}

最後,讓我們使用任務ID 49完成此任務:

 

POST http://127.0.0.1:8080/activiti-rest/service/runtime/tasks/53

這是一個POST請求,我們需要發送操作字段來指示我們要對該任務執行的操作。我們可以“解決”,“完成”或“刪除”任務。此外,我們可以傳遞任務所需的變量數組來完成。

在我們的例子中,我們要傳遞一個字段“message”,它就是用戶消息文本字段。所以我們的要求是:

{

    "action": "complete",

     "variables": [{

         "name": "message",

         "value": "This is a User Input Message"

     }]

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章