在JBPM的使用過程中,由於JBPM完全屏蔽了流程內部的細節。所以有時候很難從全局上掌握流行的運行情況。比如你提交一個請求,只知道請求提交了,通常你是不知道提交到那裏,也不知道你的請求目前在那個位置。這樣必須專門通過程序去查看流程的整體運行情況。查看的方式越簡單明瞭越好。
我採用圖片的方式,能夠顯示出流程進過的歷史和當前任務所在的節點。方便用戶查詢。
這個技術分成兩個重要部分。第一個是查詢當前流程的流程定義圖片,將其轉換成輸出流。第二點是將查詢任務經過的節點和當前節點,得到他們的座標。在html中使用圖像標註出來。
一:獲得流程定義圖片。
- public InputStream findProcessInstancePic(String processInstanceId) {
- ProcessInstance processInstance = executionService
- .findProcessInstanceById(processInstanceId);
- String processDefinitionId = processInstance.getProcessDefinitionId();
- ProcessDefinition processDefinition = repositoryService
- .createProcessDefinitionQuery()
- .processDefinitionId(processDefinitionId).uniqueResult();
- return repositoryService.getResourceAsStream(
- processDefinition.getDeploymentId(),
- processDefinition.getImageResourceName());
- }
這個方法是通過流程實例ID獲取流程定義,然後將流程定義對應的圖片得到。返回輸出流。流程定義圖片是部署流程的時候和流程定義一起部署到JBPM中的。得到圖片以後,在界面使用img標籤顯示出圖片。
- </center>
- <img src="${ctx}/service/processInstance/pic.do?processInstanceId=${id }" style="position:absolute;left:0px;top:0px;"/>
- <c:if test="${activityCoordinates!=null }">
- <div
- style="position:absolute;border:3px solid red;left:${activityCoordinates.x }px;top:${activityCoordinates.y }px;width:${activityCoordinates.width }px;height:${activityCoordinates.height}px;"></div>
- </c:if>
- <c:if test="${ac!=null }">
- <c:forEach items="${ac }" var="a">
- <div
- style="position:absolute;border:3px solid blue;left:${a.x }px;top:${a.y }px;width:${a.width }px;height:${a.height}px;"></div>
- </c:forEach>
- </c:if>
- </body>
- </html>
其中
- <imgsrcimgsrc="${ctx}/service/processInstance/pic.do?processInstanceId=${id }"style="position:absolute;left:0px;top:0px;"/>
請求一個controller顯示圖片。
controller代碼如下:
- /**
- * 顯示流程圖片
- *
- * @param request
- * @param response
- * @param id
- */
- @RequestMapping("/service/processInstance/pic.do")
- public void pic(HttpServletRequest request, HttpServletResponse response,
- String processInstanceId) {
- InputStream inputStream = workflowManager
- .findProcessInstancePic(processInstanceId);
- PrintWriter pw = null;
- if (inputStream == null) {
- try {
- pw = response.getWriter();
- pw.write("error");
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- pw.close();
- }
- } else {
- byte[] b = new byte[1024];
- int len = -1;
- ServletOutputStream sos = null;
- try {
- sos = response.getOutputStream();
- while ((len = inputStream.read(b, 0, 1024)) != -1) {
- sos.write(b, 0, len);
- }
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- if (sos != null) {
- try {
- sos.close();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
- }
二:顯示流程座標。
首先根據流程實例ID查詢出該流程實例進過的節點的名稱。然後再在流程定義中查詢這些節點的座標。
- public ActivityCoordinates findActivityCoordinates(String id) {
- ProcessInstance processInstance = executionService
- .findProcessInstanceById(id);
- if (null==processInstance||processInstance.isSuspended()) {
- return null;
- }
- Set<String> activityNames = processInstance.findActiveActivityNames();
- return repositoryService.getActivityCoordinates(processInstance
- .getProcessDefinitionId(), activityNames.iterator().next());
- }
- @Override
- public List<ActivityCoordinates> findHistoryActivityInfo(String processId) {
- List<ActivityCoordinates> activityCoordinates = new ArrayList<ActivityCoordinates>();
- List<HistoryActivityInstance> hisIns = historyService.createHistoryActivityInstanceQuery().processInstanceId(processId).list();
- ProcessInstance processInstance = executionService.findProcessInstanceById(processId);
- if (null==processInstance||processInstance.isSuspended()) {
- return null;
- }
- for(Iterator<HistoryActivityInstance> iter = hisIns.iterator();iter.hasNext() ; ){
- activityCoordinates.add(repositoryService.getActivityCoordinates(processInstance.getProcessDefinitionId(), iter.next().getActivityName()));
- }
- return activityCoordinates;
- }
其中第一個方法是返回當前節點座標,第二個方法是返回進過節點座標(包括當前節點,這就需要去掉當前的節點),這個操作在controller中完成,然後返回到頁面中。
- /**
- * 顯示流程座標
- *
- * @param request
- * @param id
- * @return
- */
- @RequestMapping("service/processInstance/view.do")
- public String view(HttpServletRequest request, String id) {
- // 流程圖活動座標
- ActivityCoordinates activityCoordinates = workflowManager
- .findActivityCoordinates(id);
- List<ActivityCoordinates> ac = null;
- if(activityCoordinates != null){
- ac = workflowManager.findHistoryActivityInfo(id);
- ac.remove(activityCoordinates);
- }
- request.setAttribute("ac", ac);
- request.setAttribute("activityCoordinates", activityCoordinates);
- request.setAttribute("id", id);
- return "/mtdev/module/myflow/image";
- }
jsp界面和上面的一樣。這裏的關鍵是使用div在圖片上標記出節點。給div加上邊框,看起來就和圖片合在一起一樣。
下面是效果圖。
更好更多地JBPM博客地址:http://blog.csdn.net/lsh6688/article/category/1189610