核心 API
RepositoryService:管理流程定義部署資源 (BPMN XML、PNG 圖片)。
RuntimeService:查詢執行中流程實例、當前活動節點。
TaskService:查詢待辦任務、關聯流程實例。
場景一:獨立查看部署圖片
public void viewDeployedImage(String deploymentId) throws IOException {
// 1. 取得部署下所有資源名稱
List<String> names = repositoryService.getDeploymentResourceNames(deploymentId);
String imageName = names.stream().filter(n -> n.endsWith(".png")).findFirst().orElse(null);
if (imageName == null) throw new IllegalStateException("無流程圖片");
// 2. 讀取圖片輸入流
InputStream in = repositoryService.getResourceAsStream(deploymentId, imageName);
// 3. 輸出到檔案或 HTTP 響應
Files.copy(in, Paths.get("D:/" + imageName), StandardCopyOption.REPLACE_EXISTING);
}
場景二:Web 頁面直接顯示圖片
@GetMapping("/process/image")
public void viewImage(@RequestParam String deploymentId,
@RequestParam String imageName,
HttpServletResponse resp) throws IOException {
InputStream in = repositoryService.getResourceAsStream(deploymentId, imageName);
resp.setContentType("image/png");
IOUtils.copy(in, resp.getOutputStream());
}
// 前端: 
場景三:查看當前任務對應流程圖並高亮節點
- 取得流程定義:
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult();
- 取得當前活動 ID:
ProcessInstance pi = runtimeService.createProcessInstanceQuery()
.processInstanceId(task.getProcessInstanceId()).singleResult();
String currentActivityId = pi.getActivityId();
- 解析座標:
ProcessDefinitionEntity pde = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(pd.getId());
ActivityImpl activity = pde.findActivity(currentActivityId);
// 座標: activity.getX(), getY(), getWidth(), getHeight()
- 前端繪製高亮:
後端返回 JSON `{deploymentId, imageName, x, y, width, height}`。
前端 `
` 疊加 `` 定位高亮框。
完整 Controller 範例
@RestController
@RequestMapping("/activiti")
public class ProcessImageController {
@Autowired RepositoryService repositoryService;
@Autowired RuntimeService runtimeService;
@Autowired TaskService taskService;
@GetMapping("/current-image")
public Map<String, Object> currentImage(@RequestParam String taskId) {
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
ProcessInstance pi = runtimeService.createProcessInstanceQuery()
.processInstanceId(task.getProcessInstanceId()).singleResult();
ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
.processDefinitionId(task.getProcessDefinitionId()).singleResult();
ProcessDefinitionEntity pde = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(pd.getId());
ActivityImpl act = pde.findActivity(pi.getActivityId());
Map<String, Object> result = new HashMap<>();
result.put("deploymentId", pd.getDeploymentId());
result.put("imageName", pd.getDiagramResourceName());
result.put("x", act.getX());
result.put("y", act.getY());
result.put("width", act.getWidth());
result.put("height", act.getHeight());
return result;
}
}
注意事項
- 圖片生成:部署時需設定
createDiagramOnDeploy=true (預設) 或手動生成 PNG。
- 字體:Linux 伺服器需安裝中文字體 (如
wqy-zenhei),否則圖片中文顯示方塊。
- 多實例/子流程:
pi.getActivityId() 可能返回多實例主體節點,需根據業務判斷高亮範圍。
- 上一篇文章: Java 生成 CSV 檔案完整實戰:UTF-8 BOM、大數據流式寫入、Web 下載
- 下一篇文章: Java JDBC 驅動載入機制詳解:Class.forName、DriverManager、SPI 原理