4. 输入边界设计:导出请求的标准化接口定义、参数校验规则、请求上下文传递
报表导出模块的输入边界是系统与外部交互的第一道防线。一个设计良好的输入边界,能够确保导出请求的完整性、合法性与可追溯性。本章节围绕标准化接口定义、参数校验规则以及请求上下文传递三个核心维度展开,构建稳固的导出请求入口。
4.1 标准化接口定义
导出请求接口采用统一的RESTful风格设计,所有导出操作均通过单一端点接收请求,避免因接口分散导致维护成本上升。接口定义遵循以下原则:
- 统一入口:所有报表导出请求统一使用
POST /api/v1/export端点。 - 请求体结构:使用JSON格式承载参数,包含报表标识、模板配置、输出格式、请求上下文等核心字段。
- 响应约定:同步导出直接返回文件流;异步导出返回任务ID,供客户端轮询进度。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
reportCode |
String | 是 | 报表唯一编码,用于定位报表定义 |
templateId |
String | 否 | 模板标识,为空则使用默认模板 |
format |
String | 是 | 输出格式:PDF、EXCEL、CSV、HTML |
params |
Map<String, Object> | 否 | 报表查询参数键值对 |
context |
Object | 是 | 请求上下文,包含用户、租户、语言等信息 |
async |
Boolean | 否 | 是否异步导出,默认false |
接口设计要点:params 字段采用松散键值对结构,允许不同报表携带差异化的查询条件,避免接口定义随报表数量膨胀而频繁变更。模板引擎在渲染阶段根据报表定义解析 params 中的具体字段。
// 导出请求示例(JSON)
{
"reportCode": "SALES_MONTHLY",
"templateId": "template_v2",
"format": "PDF",
"params": {
"startDate": "2025-01-01",
"endDate": "2025-01-31",
"region": "华东"
},
"context": {
"userId": "u10086",
"tenantId": "t_aliyun",
"locale": "zh-CN",
"timezone": "Asia/Shanghai"
},
"async": true
}
4.2 参数校验规则
参数校验是输入边界的核心防线,采用分层校验策略,兼顾性能与安全性。校验规则分为三个层级:
- 基础格式校验:检查必填字段是否存在、字段类型是否正确、枚举值是否在允许范围内。
- 业务逻辑校验:验证报表编码是否已注册、模板是否对应当前报表、参数组合是否满足报表定义要求。
- 安全校验:防止SQL注入、XSS攻击、参数溢出等安全风险。
| 校验层级 | 校验项 | 失败处理 |
|---|---|---|
| 基础格式 | reportCode 非空、format 属于枚举、context 必填 | 返回 400 Bad Request,明确错误字段 |
| 业务逻辑 | reportCode 存在且已发布、templateId 与报表匹配 | 返回 404 或 422,附带业务错误码 |
| 安全校验 | params 值长度限制、特殊字符过滤、数值范围检查 | 返回 400,拒绝请求并记录安全日志 |
最佳实践:建议使用声明式校验注解(如Jakarta Validation的 @NotNull、@Size)配合自定义校验器实现业务规则。校验失败时返回统一错误结构,包含 code、message、field 三个字段,便于前端定位问题。
// 校验失败响应示例
{
"code": "EXPORT_PARAM_INVALID",
"message": "报表编码不能为空",
"field": "reportCode"
}
4.3 请求上下文传递
请求上下文承载了导出操作所需的用户身份、租户隔离、国际化等环境信息。上下文对象在接口层被解析,并通过线程局部变量或显式参数传递至整个导出链路。
上下文传递需关注以下关键点:
- 线程安全:使用
InheritableThreadLocal或TransmittableThreadLocal确保异步任务能正确继承上下文。 - 租户隔离:数据源路由、模板资源加载均需根据
tenantId进行隔离,防止跨租户数据泄露。 - 国际化支持:
locale字段影响日期格式、数字格式、错误提示语言,模板引擎在渲染时根据该字段选择对应的资源包。 - 审计日志:
userId和tenantId必须记录到导出日志中,用于操作追溯和用量统计。
常见陷阱:在异步导出场景中,如果使用线程池执行导出任务,务必在提交任务前将上下文快照复制到任务对象中,避免线程复用导致上下文错乱。推荐使用 ContextAwareRunnable 包装类自动处理上下文传递。
4.4 输入边界整体架构
将标准化接口、参数校验、上下文传递三者整合,形成完整的输入边界架构。下图展示了请求从进入系统到进入核心处理流程的完整路径。
输入边界设计的关键在于“收口”与“透传”的平衡:接口层收窄入口,校验层过滤无效请求,上下文层透传环境信息。三层协作确保只有合法、完整、可追溯的导出请求才能进入核心处理流程,为后续的模板引擎集成与参数配置奠定坚实基础。