Springboot 2.0+activiti 7 Integration--Create your own business process

Keywords: Java MySQL Database xml

With the activiti framework, you first need to create a bpmn flowchart. There are two choices: one is the plug-in that comes with the ide (eclipse is good, not to mention it; the other is the plug-in that is really hard to use and has not been updated for several years); the other is the tool that activiti officially provides. activiti-app (Version 6.0, which we only use to draw), put activiti-app.war on tomcat to run.

## 1, Drawing flowchart

Create a leave process

The flowchart is as follows:


Key attributes:

  1. Each rectangle box is a userTask, with the most critical property: Assignments Task Specifier
    Since the identity section of activiti is not used, I choose to dynamically pass in a parameter (dynamic variable names cannot be repeated):
  2. Each connector is a sequenceFlow, and the key properties are: Flow conditional sequential Flow condition; conditional expression can be set; variable names of branches must be consistent here, such as ${audit==1"} if an audit passes ${audit==1"} and ${audit==1"}

2. Import Flowchart

Download the drawn flowchart locally, create a new file (leave.bpmn20.xml) in the processes directory, and copy the flowchart into the XML with the text open:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
    <process id="leave" name="Leave process" isExecutable="true">
        <startEvent id="startEvent1" name="start"></startEvent>
        <userTask id="sid-E9DA7720-703C-4AA1-9233-5B4977C4D7FA" name="Fill in the application" activiti:assignee="${user}"><!--activiti:assignee Task Designator-->
            <extensionElements>
                <modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
            </extensionElements>
        </userTask>
        <sequenceFlow id="sid-782B5EB0-C3E4-4EA8-B47C-001493E8CFAA" sourceRef="startEvent1" targetRef="sid-E9DA7720-703C-4AA1-9233-5B4977C4D7FA"></sequenceFlow>
        <userTask id="sid-F30892E7-AD40-44CE-8FE1-911564290536" name="Leader approval" activiti:assignee="${approve}">
            <extensionElements>
                <modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
            </extensionElements>
        </userTask>
        <sequenceFlow id="sid-9BAB7E50-7E04-4C87-8448-ECDF79CB4405" sourceRef="sid-E9DA7720-703C-4AA1-9233-5B4977C4D7FA" targetRef="sid-F30892E7-AD40-44CE-8FE1-911564290536"></sequenceFlow>
        <exclusiveGateway id="sid-C7396408-A226-4385-9E87-C63DA1295BEE"></exclusiveGateway>
        <sequenceFlow id="sid-4570FB2C-F000-4EB9-961B-795DFD3CD037" sourceRef="sid-F30892E7-AD40-44CE-8FE1-911564290536" targetRef="sid-C7396408-A226-4385-9E87-C63DA1295BEE"></sequenceFlow>
        <endEvent id="sid-E8EA0FBB-EAE1-4316-BAAE-1465DD35D4EA" name="End"></endEvent>
        <!--sequenceFlow Process Branch-->
        <sequenceFlow id="sid-715DC950-61C4-4AA8-9662-A6FD71611EAA" name="Audit Failed" sourceRef="sid-C7396408-A226-4385-9E87-C63DA1295BEE" targetRef="sid-E9DA7720-703C-4AA1-9233-5B4977C4D7FA">
            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${audit==0}]]></conditionExpression>
        </sequenceFlow>
        <sequenceFlow id="sid-EA1D4887-5497-43DE-9D57-A03D3B719681" name="Approval Passed" sourceRef="sid-C7396408-A226-4385-9E87-C63DA1295BEE" targetRef="sid-E8EA0FBB-EAE1-4316-BAAE-1465DD35D4EA">
            <conditionExpression xsi:type="tFormalExpression"><![CDATA[${audit==1}]]></conditionExpression>
        </sequenceFlow>
    </process>
    <bpmndi:BPMNDiagram id="BPMNDiagram_leave">
        <bpmndi:BPMNPlane bpmnElement="leave" id="BPMNPlane_leave">
            <bpmndi:BPMNShape bpmnElement="startEvent1" id="BPMNShape_startEvent1">
                <omgdc:Bounds height="30.0" width="30.0" x="90.0" y="150.0"></omgdc:Bounds>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="sid-E9DA7720-703C-4AA1-9233-5B4977C4D7FA" id="BPMNShape_sid-E9DA7720-703C-4AA1-9233-5B4977C4D7FA">
                <omgdc:Bounds height="80.0" width="100.0" x="165.0" y="125.0"></omgdc:Bounds>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="sid-F30892E7-AD40-44CE-8FE1-911564290536" id="BPMNShape_sid-F30892E7-AD40-44CE-8FE1-911564290536">
                <omgdc:Bounds height="80.0" width="100.0" x="300.0" y="125.0"></omgdc:Bounds>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="sid-C7396408-A226-4385-9E87-C63DA1295BEE" id="BPMNShape_sid-C7396408-A226-4385-9E87-C63DA1295BEE">
                <omgdc:Bounds height="40.0" width="40.0" x="450.0" y="145.0"></omgdc:Bounds>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="sid-E8EA0FBB-EAE1-4316-BAAE-1465DD35D4EA" id="BPMNShape_sid-E8EA0FBB-EAE1-4316-BAAE-1465DD35D4EA">
                <omgdc:Bounds height="28.0" width="28.0" x="540.0" y="151.0"></omgdc:Bounds>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNEdge bpmnElement="sid-782B5EB0-C3E4-4EA8-B47C-001493E8CFAA" id="BPMNEdge_sid-782B5EB0-C3E4-4EA8-B47C-001493E8CFAA">
                <omgdi:waypoint x="120.0" y="165.0"></omgdi:waypoint>
                <omgdi:waypoint x="165.0" y="165.0"></omgdi:waypoint>
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge bpmnElement="sid-9BAB7E50-7E04-4C87-8448-ECDF79CB4405" id="BPMNEdge_sid-9BAB7E50-7E04-4C87-8448-ECDF79CB4405">
                <omgdi:waypoint x="265.0" y="165.0"></omgdi:waypoint>
                <omgdi:waypoint x="300.0" y="165.0"></omgdi:waypoint>
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge bpmnElement="sid-4570FB2C-F000-4EB9-961B-795DFD3CD037" id="BPMNEdge_sid-4570FB2C-F000-4EB9-961B-795DFD3CD037">
                <omgdi:waypoint x="400.0" y="165.20746887966806"></omgdi:waypoint>
                <omgdi:waypoint x="450.4166666666667" y="165.41666666666666"></omgdi:waypoint>
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge bpmnElement="sid-715DC950-61C4-4AA8-9662-A6FD71611EAA" id="BPMNEdge_sid-715DC950-61C4-4AA8-9662-A6FD71611EAA">
                <omgdi:waypoint x="470.5" y="145.5"></omgdi:waypoint>
                <omgdi:waypoint x="470.5" y="26.0"></omgdi:waypoint>
                <omgdi:waypoint x="215.0" y="26.0"></omgdi:waypoint>
                <omgdi:waypoint x="215.0" y="125.0"></omgdi:waypoint>
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge bpmnElement="sid-EA1D4887-5497-43DE-9D57-A03D3B719681" id="BPMNEdge_sid-EA1D4887-5497-43DE-9D57-A03D3B719681">
                <omgdi:waypoint x="489.6144578313253" y="165.3855421686747"></omgdi:waypoint>
                <omgdi:waypoint x="540.0002509882663" y="165.0838308324056"></omgdi:waypoint>
            </bpmndi:BPMNEdge>
        </bpmndi:BPMNPlane>
    </bpmndi:BPMNDiagram>
</definitions>

3. Configure application.yml


spring:
  datasource:
    #Data Source Basic Configuration
    username: root
    password: root
    url: jdbc:mysql://localhost/activiti?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&nullCatalogMeansCurrent=true&useSSL=false&useLegacyDatetimeCode=false
    driver-class-name: com.mysql.cj.jdbc.Driver
  activiti:
    # Open History Library
    db-history-used: true
    history-level: audit

The level of historical information can be configured as follows (activiti7 feels like none by default):

none: Ignore all historical archives.This is the best performance state for the process to execute, but no historical information is available.

Activity: Save all process instance information and activity instance information.At the end of the process instance, the latest variable value from the last process instance is assigned to the historical variable.Details of the process will not be saved.

audit: It holds all process instance information, activity information, and ensures that all variables and submitted form properties are synchronized so that all user interaction information is traceable and can be used for auditing.

full: This is the highest-level archive of historical information and also the slowest.This level stores information that occurs during auditing and all other details, mainly updating process variables.

4. Start a task

    /**
     * Start a leave process
     * @param user User key
     * @param processDefinitionKey Flowchart key Each process has a corresponding key This is fixed within a process written in bpmn
     */
    void startLeaveProcess(String user,String processDefinitionKey){
        System.out.println(user+"Start a leave process:"+ processDefinitionKey);
        HashMap<String, Object> variables=new HashMap<>();
        variables.put("user", user);//userKey is specified in the process variable above

        ProcessInstance instance = runtimeService
                .startProcessInstanceByKey(processDefinitionKey,variables);
        System.out.println("Process Instances ID:"+instance.getId());
        System.out.println("Process Definition ID:"+instance.getProcessDefinitionId());
        System.out.println("==================================================================");
    }

Run result:

Zhang San starts a leave process:
Process Instance ID:34f2f038-0d07-11ea-b319-9c5c8e7034f6
 Process Definition ID:leave:1:32f7bc77-0d07-11ea-b319-9c5c8e7034f6
==================================================================

Notice the changes in the database:

mysql> select ID_,REV_,PROC_INST_ID_,NAME_,ASSIGNEE_ from act_ru_task;
+--------------------------------------+------+--------------------------------------+----------+-----------+
| ID_                                  | REV_ | PROC_INST_ID_                        | NAME_    | ASSIGNEE_ |
+--------------------------------------+------+--------------------------------------+----------+-----------+
| 34f8958d-0d07-11ea-b319-9c5c8e7034f6 |    1 | 34f2f038-0d07-11ea-b319-9c5c8e7034f6 | Fill in the application | Zhang San      |
+--------------------------------------+------+--------------------------------------+----------+-----------+
1 row in set

5. Query the current process according to the executor

/**
     * Query current task process
     */
    void queryLeaveProcessING(String assignee){
        System.out.println(assignee+"Query your current process:");
        List<Task> list = taskService.createTaskQuery()//Create Task Query Object
                .taskAssignee(assignee)//Specify Personal Task Query
                .list();
        if(list!=null && list.size()>0){
            for(Task task:list){
                System.out.println("task ID:"+task.getId());
                System.out.println("Task Name:"+task.getName());
                System.out.println("Task creation time:"+task.getCreateTime());
                System.out.println("Task Manager:"+task.getAssignee());
                System.out.println("Process Instances ID: "+task.getProcessInstanceId());
                System.out.println("target of execution ID:"+task.getExecutionId());
                System.out.println("Process Definition ID:"+task.getProcessDefinitionId());
                Map<String, Object> map = task.getProcessVariables();
                for (Map.Entry<String, Object> m : map.entrySet()) {
                    System.out.println("key:" + m.getKey() + " value:" + m.getValue());
                }
                for (Map.Entry<String, Object> m : task.getTaskLocalVariables().entrySet()) {
                    System.out.println("key:" + m.getKey() + " value:" + m.getValue());
                }

            }
        }
        System.out.println("==================================================================");
    }

Run result:

Zhang San queries his current process:
Task ID:34f8958d-0d07-11ea-b319-9c5c8e7034f6
 Task Name: Fill in the application
 Task creation time: Fri Nov 22 17:05:19 CST 2019
 Managing the task: Zhang San
 Process Instance ID: 34f2f038-0d07-11ea-b319-9c5c8e7034f6
 Execution object ID:34f3b38a-0d07-11ea-b319-9c5c8e7034f6
 Process Definition ID:leave:1:32f7bc77-0d07-11ea-b319-9c5c8e7034f6
==================================================================

6. Submit to Leader for Review

    void completeTask(String approve,String taskId){
        System.out.println(approve+": Submit your own process:"+taskId);
        //Task ID
        HashMap<String, Object> variables=new HashMap<>();
        variables.put("approve", approve);//userKey is specified in the process variable above
        taskService.complete(taskId,variables);

        System.out.println("Complete Task: Task ID: "+taskId);
        System.out.println("==================================================================");
    }

Run result:

Leader Li Si: Submit own process: 34f8958d-0d07-11ea-b319-9c5c8e7034f6
 Complete Task: Task ID: 34f8958d-0d07-11ea-b319-9c5c8e7034f6
==================================================================

Database:

mysql> select ID_,REV_,PROC_INST_ID_,NAME_,ASSIGNEE_ from act_ru_task;
+--------------------------------------+------+--------------------------------------+----------+-----------+
| ID_                                  | REV_ | PROC_INST_ID_                        | NAME_    | ASSIGNEE_ |
+--------------------------------------+------+--------------------------------------+----------+-----------+
| e60702be-0d08-11ea-8a0a-9c5c8e7034f6 |    1 | 34f2f038-0d07-11ea-b319-9c5c8e7034f6 | Leader approval | Leader Li Si  |
+--------------------------------------+------+--------------------------------------+----------+-----------+
1 row in set

7. Leadership review and approval

    void completeTask(String user,String taskId,int audit){
        System.out.println(user+": Submit your own process:"+taskId+" ;Pass or not:"+audit);
        //Task ID
        HashMap<String, Object> variables=new HashMap<>();
        variables.put("audit", audit);//userKey is specified in the process variable above
        taskService.complete(taskId,variables);

        System.out.println("Complete Task: Task ID: "+taskId);
        System.out.println("==================================================================");
    }

Run result:

Leader Li 4: Submit your own process: e60702be-0d08-11ea-8a0a-9c5c8e7034f6; Pass or not:1
 Complete Task: Task ID: e60702be-0d08-11ea-8a0a-9c5c8e7034f6
==================================================================

Database:

mysql> select ID_,REV_,PROC_INST_ID_,NAME_,ASSIGNEE_ from act_ru_task;
Empty set

8. Query historical data

Query according to process ID:

 List<HistoricTaskInstance> list=historyService // History-related Service s
                .createHistoricTaskInstanceQuery() // Create Historical Activity Instance Query
                .processInstanceId("34f2f038-0d07-11ea-b319-9c5c8e7034f6") // Execution process instance id
                .orderByTaskCreateTime()
                .asc()
                .list();
        for(HistoricTaskInstance hai:list){
            System.out.println("activity ID:"+hai.getId());
            System.out.println("Process Instances ID:"+hai.getProcessInstanceId());
            System.out.println("Activity name:"+hai.getName());
            System.out.println("Handler:"+hai.getAssignee());
            System.out.println("Start time:"+hai.getStartTime());
            System.out.println("End time:"+hai.getEndTime());
            System.out.println("==================================================================");
        }

Run result:

Activity ID:34f8958d-0d07-11ea-b319-9c5c8e7034f6
 Process Instance ID:34f2f038-0d07-11ea-b319-9c5c8e7034f6
 Activity Name: Fill in Application
 Handler: Zhang San
 Start time: Fri Nov 22 17:05:19 CST 2019
 End time: Fri Nov 22 17:17:25 CST 2019
==================================================================
Activity ID:e60702be-0d08-11ea-8a0a-9c5c8e7034f6
 Process Instance ID:34f2f038-0d07-11ea-b319-9c5c8e7034f6
 Activity Name: Leader Approval
 Manager: Leader Li Si
 Start time: Fri Nov 22 17:17:25 CST 2019
 End time: Fri Nov 22 17:31:03 CST 2019
==================================================================

Query personal history:

List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().taskAssignee("Zhang San").orderByTaskCreateTime().asc().list();
        for(HistoricTaskInstance hai:list){
            System.out.println("activity ID:"+hai.getId());
            System.out.println("Process Instances ID:"+hai.getProcessInstanceId());
            System.out.println("Activity name:"+hai.getName());
            System.out.println("Handler:"+hai.getAssignee());
            System.out.println("Start time:"+hai.getStartTime());
            System.out.println("End time:"+hai.getEndTime());
            System.out.println("==================================================================");
        }

Run result:

Activity ID:34f8958d-0d07-11ea-b319-9c5c8e7034f6
 Process Instance ID:34f2f038-0d07-11ea-b319-9c5c8e7034f6
 Activity Name: Fill in Application
 Handler: Zhang San
 Start time: Fri Nov 22 17:05:19 CST 2019
 End time: Fri Nov 22 17:17:25 CST 2019
==================================================================

Database:

mysql> select ID_,PROC_INST_ID_,NAME_,ASSIGNEE_ from act_hi_taskinst;
+--------------------------------------+--------------------------------------+----------+-----------+
| ID_                                  | PROC_INST_ID_                        | NAME_    | ASSIGNEE_ |
+--------------------------------------+--------------------------------------+----------+-----------+
| 34f8958d-0d07-11ea-b319-9c5c8e7034f6 | 34f2f038-0d07-11ea-b319-9c5c8e7034f6 | Fill in the application | Zhang San      |
| e60702be-0d08-11ea-8a0a-9c5c8e7034f6 | 34f2f038-0d07-11ea-b319-9c5c8e7034f6 | Leader approval | Leader Li Si  |
+--------------------------------------+--------------------------------------+----------+-----------+
2 rows in set

9. Complete test class code

package com.example.activitidemo2;

import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SpringBootTest
class ActivitiDemo2ApplicationTests {

    @Resource
    RepositoryService repositoryService;

    @Resource
    RuntimeService runtimeService;

    @Resource
    TaskService taskService;

    @Resource
    HistoryService historyService;

    @Test
    void contextLoads() {
        System.out.println("Number of process definitions : "
                + repositoryService.createProcessDefinitionQuery().count());
        System.out.println("Number of tasks : " + taskService.createTaskQuery().count());
        runtimeService.startProcessInstanceByKey("oneTaskProcess");
        System.out.println("Number of tasks after process start: " + taskService.createTaskQuery().count());
    }


    @Test
    void testProcess(){
        //Zhang San starts a vacation process
        String user = "Zhang San";
        String approve = "Leader Li Si";
//        startLeaveProcess(user,"leave");


        //Zhang Sanquery his own process
//        queryLeaveProcessING(user);


//        Submitted to Leader Li Si for Review
//        String taskId = "34f8958d-0d07-11ea-b319-9c5c8e7034f6";
//        completeTask(approve,taskId);



        //Leader Li Si inquires about his own process
//        queryLeaveProcessING(approve);


        //Li Si submits his own process
        completeTask(approve,"e60702be-0d08-11ea-8a0a-9c5c8e7034f6",1);


        //Zhang San Queries His Historical Process
//        queryHistoryTask(userKey);
    }


    /**
     * Start a leave process
     * @param user User key
     * @param processDefinitionKey Flowchart key Each process has a corresponding key This is fixed within a process written in bpmn
     */
    void startLeaveProcess(String user,String processDefinitionKey){
        System.out.println(user+"Start a leave process:"+ processDefinitionKey);
        HashMap<String, Object> variables=new HashMap<>();
        variables.put("user", user);//userKey is specified in the process variable above

        ProcessInstance instance = runtimeService
                .startProcessInstanceByKey(processDefinitionKey,variables);
        System.out.println("Process Instances ID:"+instance.getId());
        System.out.println("Process Definition ID:"+instance.getProcessDefinitionId());
        System.out.println("==================================================================");
    }


    /**
     * Query current task process
     */
    void queryLeaveProcessING(String assignee){
        System.out.println(assignee+"Query your current process:");
        List<Task> list = taskService.createTaskQuery()//Create Task Query Object
                .taskAssignee(assignee)//Specify Personal Task Query
                .list();
        if(list!=null && list.size()>0){
            for(Task task:list){
                System.out.println("task ID:"+task.getId());
                System.out.println("Task Name:"+task.getName());
                System.out.println("Task creation time:"+task.getCreateTime());
                System.out.println("Task Manager:"+task.getAssignee());
                System.out.println("Process Instances ID: "+task.getProcessInstanceId());
                System.out.println("target of execution ID:"+task.getExecutionId());
                System.out.println("Process Definition ID:"+task.getProcessDefinitionId());
                Map<String, Object> map = task.getProcessVariables();
                for (Map.Entry<String, Object> m : map.entrySet()) {
                    System.out.println("key:" + m.getKey() + " value:" + m.getValue());
                }
                for (Map.Entry<String, Object> m : task.getTaskLocalVariables().entrySet()) {
                    System.out.println("key:" + m.getKey() + " value:" + m.getValue());
                }

            }
        }
        System.out.println("==================================================================");
    }



    @Test
    void completeTask(String approve,String taskId){
        System.out.println(approve+": Submit your own process:"+taskId);
        //Task ID
        HashMap<String, Object> variables=new HashMap<>();
        variables.put("approve", approve);//userKey is specified in the process variable above
        taskService.complete(taskId,variables);

        System.out.println("Complete Task: Task ID: "+taskId);
        System.out.println("==================================================================");
    }


    @Test
    void completeTask(String user,String taskId,int audit){
        System.out.println(user+": Submit your own process:"+taskId+" ;Pass or not:"+audit);
        //Task ID
        HashMap<String, Object> variables=new HashMap<>();
        variables.put("audit", audit);//userKey is specified in the process variable above
        taskService.complete(taskId,variables);

        System.out.println("Complete Task: Task ID: "+taskId);
        System.out.println("==================================================================");
    }



    @Test
    void queryHistoryTask(){
        List<HistoricTaskInstance> list=historyService // History-related Service s
                .createHistoricTaskInstanceQuery() // Create Historical Activity Instance Query
                .processInstanceId("34f2f038-0d07-11ea-b319-9c5c8e7034f6") // Execution process instance id
                .orderByTaskCreateTime()
                .asc()
                .list();
        for(HistoricTaskInstance hai:list){
            System.out.println("activity ID:"+hai.getId());
            System.out.println("Process Instances ID:"+hai.getProcessInstanceId());
            System.out.println("Activity name:"+hai.getName());
            System.out.println("Handler:"+hai.getAssignee());
            System.out.println("Start time:"+hai.getStartTime());
            System.out.println("End time:"+hai.getEndTime());
            System.out.println("==================================================================");
        }
//        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery(). taskAssignee("Zhang San"). orderByTaskCreateTime().asc().list();
//        for(HistoricTaskInstance hai:list){
//            System.out.println("Activity ID:"+hai.getId()));
//            System.out.println("Process Instance ID:"+hai.getProcessInstanceId()));
//            System.out.println("Activity name:"+hai.getName()));
//            System.out.println("Administrator:"+hai.getAssignee()));
//            System.out.println("Start time:"+hai.getStartTime()));
//            System.out.println("End time:"+hai.getEndTime()));
//            System.out.println("==================================================================");
//        }


    }

}

Posted by neroag on Sun, 24 Nov 2019 11:36:53 -0800