外观
快速开始
本例完成“准备示例文件 → 为当前用户登记记录 → 查询列表 → 访问文件”的流程。记录写入和查询同步完成,不需要启动异步任务。
前提是已有可运行的 EFC Web 应用,具备登录认证、MySQL 数据源与驱动,以及框架基础 Bean。当前源码基线为 Java 25、Spring Boot 4.1.0,模块版本为 4.1.0-SNAPSHOT,相关依赖需在项目 Maven 仓库或本地可用。准备一个已存在且可登录的用户。
1. 添加依赖
在应用 POM 中导入 Business BOM,并添加 App Controller。已有 BOM 不重复导入。
xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.own</groupId>
<artifactId>springboot-business-dependencies</artifactId>
<version>4.1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.own.business</groupId>
<artifactId>springboot-business-download-center-controller-app</artifactId>
</dependency>
</dependencies>该依赖带入下载中心 Business、Common、二次确认和系统日志组件;数据访问基础依赖包含 MyBatis-Plus 和 PageHelper。应用仍需完成认证装配,使 SessionUserUtil 能取得当前用户,不能仅靠请求中的 userId 建立身份。
UseBusinessDownloadCenter 已通过自动配置导入文件注册,扫描 com.own.business.download.center 下的服务、已引入的 Controller 和 Mapper,无需手动添加 @MapperScan。确认现有应用已注册基础 MapperUtil Bean,并启用分页所需的 PageHelper 配置。
若还要验证删除确认,应用应提供 StoreClient 和 StoreLockManager。单实例演示且尚未配置 Store 时,可在应用依赖中追加:
xml
<dependency>
<groupId>com.own.component</groupId>
<artifactId>springboot-component-store-starter-local</artifactId>
</dependency>已有 Store 的应用沿用原实现;多实例应使用共享 Redis Store,保持数据与锁的共享范围一致。仅引入下载中心 Controller 不保证二次确认切面生效,具体装配条件见查询与删除页。
2. 初始化数据表
在应用已有的 MySQL 数据库中执行 下载中心首次建表 SQL,创建 own_download_center 和用户查询索引 idx_download_center_user。
脚本保留当前业务源码的表结构与索引,移除了 DROP TABLE,仅用于尚未创建该表的数据库。它不是已有表的增量迁移,也不会随应用启动自动执行。
沿用现有数据源;尚未配置时,在应用 application.yml 中填写环境变量:
yaml
spring:
datasource:
url: ${DOWNLOAD_CENTER_JDBC_URL}
username: ${DOWNLOAD_CENTER_DB_USERNAME}
password: ${DOWNLOAD_CENTER_DB_PASSWORD}
driver-class-name: com.mysql.cj.jdbc.DriverDOWNLOAD_CENTER_JDBC_URL 是应用的 MySQL JDBC 地址。下载中心没有额外的数据源、存储供应商或任务线程池配置。
3. 准备文件与登记入口
在应用 src/main/resources/static/download-center-demo.csv 中写入以下无敏感信息的演示数据:
csv
item,count
demo,1本例使用应用自身的静态资源处理提供文件,需保留 Spring MVC 静态资源映射。真实业务文件的访问控制由应用或存储服务实现,下载记录的用户隔离不会自动保护静态 URL。
把下面的演示 Controller 放到应用启动类能够扫描的包中,按应用实际包名调整 package。使用 download-center-demo profile 启动应用以启用该入口,例如追加启动参数 --spring.profiles.active=download-center-demo;若应用已有 profile,应同时保留。
java
package com.example.demo;
import com.own.business.download.center.business.service.DownloadCenterService;
import com.own.business.download.center.common.entity.dto.DownloadCenterDto;
import com.own.business.download.center.common.entity.vo.DownloadCenterVo;
import com.own.component.base.login.util.SessionUserUtil;
import com.own.component.base.model.R;
import com.own.component.base.model.ResultModel;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.context.annotation.Profile;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
@Profile("download-center-demo")
@RestController
public class DownloadCenterDemoController {
private final DownloadCenterService downloadCenterService;
public DownloadCenterDemoController(DownloadCenterService downloadCenterService) {
this.downloadCenterService = downloadCenterService;
}
@PostMapping("/api/app/demo/download-center/register")
public ResultModel<DownloadCenterVo> register(HttpServletRequest request) throws IOException {
var loginUser = SessionUserUtil.getLoginUser();
var file = new ClassPathResource("static/download-center-demo.csv");
var dto = new DownloadCenterDto()
.setFileName("下载中心示例.csv")
.setFileType("csv")
.setFilePath(request.getContextPath() + "/download-center-demo.csv")
.setFileSize(file.contentLength())
.setUserId(loginUser.userId())
.setStatus(1)
.setProgress(100);
var po = dto.toPo();
po.init(loginUser);
return R.success(downloadCenterService.addByPo(po));
}
}这个新增入口属于示例应用,下载中心本身没有登记文件的 HTTP 接口。文件已经准备好,因此直接写入完成状态;po.init(loginUser) 显式初始化审计信息,归属用户仍通过 dto.userId 设置。
4. 登记、查询并打开文件
启动应用后,使用已登录的 API 客户端发起以下请求,补上应用域名、端口和实际 context path,认证头或 Cookie 沿用应用登录协议。
- 调用
POST /api/app/demo/download-center/register,无需请求体。成功后记录data.id;每次调用都会创建一条新记录。 - 调用
POST /api/app/download/center/page,使用Content-Type: application/json,请求体如下。 - 调用
GET /api/app/download/center/id/{id},将{id}替换成登记返回的 ID。 - 使用响应中的
data.filePath访问文件。本例应得到示例 CSV 内容;浏览器是否直接展示或保存取决于静态资源响应头与客户端行为。
json
{
"page": 1,
"rows": 10,
"fileName": "下载中心示例",
"status": 1
}预期成功业务码为 00000,列表在 data.list 中,应看到 fileType=csv、status=1、progress=100 和当前用户的 userId。接口不会读取文件确认其存在,也不会替应用修复下载地址。
切换另一个已登录用户后,同一记录不应出现在列表中;通过原 ID 查询详情会得到 business_not_found。响应、字段和分页约定见查询与删除。