
在企业级 AI 应用开发领域,随着微服务架构的普及,业务流程的复杂性呈指数级增长,如何高效地管理和编排多个服务之间的交互逻辑,成为技术团队面临的核心挑战。Dify 作为一款开源的工作流自动化工具,凭借其可视化流程设计、丰富的组件生态以及灵活的 API 对接能力,成为构建复杂 AI 业务流程的理想选择。本文将结合实际项目经验,详细阐述如何通过 Java 技术栈与 Dify 工作流 API 进行深度集成,实现从文件上传、流程执行到结果反馈的全链路自动化。
Dify 采用容器化部署方式,支持 Docker 快速启动。第一从官方仓库拉取最新镜像(当前稳定版本为 v1.2.0),通过以下命令启动服务:
bash
docker run -d --name dify -p 8098:80 -e DIFY_API_KEY=your_api_key langgenius/dify:1.2.0
启动成功后,访问http://localhost:8098即可进入可视化工作流设计界面。在开始设计流程前,需注意版本兼容性,本文所有案例均基于 Dify 1.2.0 版本开发,提议开发者保持版本一致以避免接口差异。
本次实战案例设计一个 “文件解析 - 数据存储” 的基础工作流,包含三个核心节点:
在 Dify 工作台中,通过拖拽组件并配置节点间的数据流,即可完成工作流的可视化搭建。需要特别注意 HTTP 请求节点的配置细节,包括目标 URL(如
http://localhost:8098/workflow/saveData)、请求方法(POST)、请求体参数(text字段绑定文档提取结果)以及失败重试策略(本案例设置重试 3 次)。
本次开发采用 Spring Boot 3.2 构建 Java 服务端,集成以下核心组件:
项目结构遵循 MVC 设计模式,包含controller(接口层)、service(业务逻辑层)、dao(数据访问层)以及config(配置层)四个核心包。

java
@RestController
@RequestMapping("/workflow")
public class WorkFlowController {
@Autowired
private WorkFlowService workFlowService;
@PostMapping("/upload")
public WorkFlowFileVo upload(@RequestParam("file") MultipartFile file) throws IOException {
return workFlowService.upload(file);
}
// 其他接口省略
}
该接口接收前端上传的文件,调用WorkFlowService的upload方法处理文件上传逻辑。需要注意@RequestParam("file")注解需与前端表单字段名一致,确保文件流正确接收。
java
@PostMapping("/runWorkFlow")
public SseEmitter runWorkFlow(@RequestBody WorkFlowRunDto workFlowRunDto) {
return workFlowService.runWorkFlow(workFlowRunDto);
}
此接口用于触发 Dify 工作流执行,返回SseEmitter对象处理服务器发送事件(Server-Sent Events, SSE),实现流式响应。通过这种方式,前端可以实时获取工作流执行状态,如workflow_started、task_processing、workflow_finished等事件。
java
@GetMapping("/workFlowInfo")
public WorkFlowExeVo workFlowRunInfo(String workflowRunId) {
return workFlowService.workFlowRunInfo(workflowRunId);
}
根据工作流执行 ID 查询实时状态,返回包含执行时间、节点状态、错误信息等数据的WorkFlowExeVo对象,便于监控和调试。
java
@Override
public WorkFlowFileVo upload(MultipartFile file) throws IOException {
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
headers.set("Authorization", difyConfig.getSaveDataAuthorization()); // 从配置获取API密钥
// 构建文件上传请求体
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", new ByteArrayResource(file.getBytes()) {
@Override
public String getFilename() {
return file.getOriginalFilename(); // 保留原始文件名
}
});
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
String uploadUrl = difyConfig.getSaveDataUrl() + "/files/upload"; // Dify文件上传API
// 发送POST请求
ResponseEntity<String> response = restTemplate.exchange(
uploadUrl, HttpMethod.POST, requestEntity, String.class
);
// 解析响应结果
WorkFlowFileVo workFlowFileVo = JSON.parseObject(response.getBody(), WorkFlowFileVo.class);
// 触发工作流执行
WorkFlowRunDto workFlowRunDto = buildWorkFlowRunDto(workFlowFileVo.getId());
this.runWorkFlow(workFlowRunDto);
return workFlowFileVo;
}
在文件上传逻辑中,通过RestTemplate构造包含文件流和 API 密钥的请求,调用 Dify 的/files/upload接口完成文件存储。上传成功后,立即触发工作流执行,实现流程自动化。
java
@Override
public SseEmitter runWorkFlow(WorkFlowRunDto workFlowRunDto) {
SseEmitter emitter = new SseEmitter(300_000L); // 设置5分钟超时
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(() -> {
try {
String runUrl = difyConfig.getSaveDataUrl() + "/workflows/run";
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", difyConfig.getSaveDataAuthorization());
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Collections.singletonList(MediaType.TEXT_EVENT_STREAM));
HttpEntity<WorkFlowRunDto> requestEntity = new HttpEntity<>(workFlowRunDto, headers);
// 使用restTemplate.execute处理流式响应
restTemplate.execute(
runUrl, HttpMethod.POST,
request -> {
request.getHeaders().setAll(requestEntity.getHeaders());
new ObjectMapper().writeValue(request.getBody(), requestEntity.getBody());
},
response -> {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(response.getBody())
)) {
String line;
boolean workflowRunIdProcessed = false;
while ((line = reader.readLine()) != null) {
if (line.startsWith("event: ping")) continue; // 跳过心跳事件
emitter.send(line); // 向前端推送事件
log.info("Workflow event: {}", line);
// 解析工作流ID
if (!workflowRunIdProcessed) {
try {
workflowRunIdProcessed = processLine(line);
} catch (Exception e) {
emitter.completeWithError(e);
}
}
}
}
emitter.complete();
return null;
}
);
} catch (Exception e) {
emitter.completeWithError(e);
} finally {
executor.shutdown();
}
});
return emitter;
}
工作流执行接口通过SseEmitter实现服务器向客户端的单向流式通信,使用独立线程处理异步请求,避免阻塞主线程。通过解析 Dify 返回的text/event-stream格式数据,提取workflow_run_id等关键信息,并实时推送至前端界面。

使用 Postman 验证文件上传接口:
json
{
"id": "23a10bfb-6203-404d-b0f8-02cdff37a689",
"name": "java命名规范.txt",
"size": "328",
"extension": "txt"
}
状态码 200 表明上传成功,返回的文件 ID 将用于触发工作流。
通过调用/runWorkFlow接口触发流程执行,观察控制台日志输出:
log
2025-04-19 11:28:36 [pool-1-thread-1] INFO WorkFlowServiceImpl - runUrl: http://localhost:8098/workflows/run
2025-04-19 11:28:38 [pool-1-thread-1] INFO WorkFlowServiceImpl - Workflow event: data: {"event":"workflow_started","workflow_run_id":"6d6a6c95-f1e9-4d83-aa9b-f8d76c349c45"}
2025-04-19 11:28:45 [pool-1-thread-1] INFO WorkFlowServiceImpl - Workflow event: data: {"event":"workflow_finished","workflow_run_id":"6d6a6c95-f1e9-4d83-aa9b-f8d76c349c45","task_id":"690c6916-5104-4284"}
工作流执行完成后,查询数据库确认数据已正确存储:
id | content |
8 | this is a test |
9 | 以下是 Java 命名规范的提取内容 |
除了本文介绍的文件解析场景,Dify 工作流还可应用于以下领域:
本文通过实际案例演示了 Java 与 Dify 工作流 API 的全流程对接,从环境搭建、流程设计到代码实现、测试验证,完整呈现了企业级应用开发中的关键技术点。通过 Dify 的可视化流程编排能力与 Java 的强类型编程优势相结合,开发者能够高效构建复杂业务逻辑,同时保持系统的可维护性和扩展性。未来,随着低代码 / 无代码技术的普及,类似 Dify 的工作流工具将在更多领域发挥核心作用,成为连接不同技术栈的桥梁。
感谢关注「AI 码力」,抓紧 AI 时代!