04-一个请求的完整旅程

发布时间:2026/10/17 21:43:24

04-一个请求的完整旅程 04-一个请求的完整旅程前面三篇讲了全景、哲学、模式。从这篇开始进入代码。以一次分页查询用户列表和一次审批通过任务为例把 HTTP 请求从浏览器到 Oracle 再回来的每一跳拆开——这一篇是后面所有引擎类文章的索引。文章目录04-一个请求的完整旅程一、例一分页查询 POST /ea/page/SYS_USER_s第1跳JwtAuthFilterplatform模块第2跳EaControllerformbuilder模块第3跳EaEnginemetadata模块第4跳返回二、例二审批通过 POST /api/workflow/process/complete三、两条链的公共部分四、系列后续怎么展开一、例一分页查询 POST /ea/page/SYS_USER_s第1跳JwtAuthFilterplatform模块browise-platform/src/main/java/com/browise/platform/auth/JwtAuthFilter.java6.0KBorder1 的原生 Filter不依赖Spring Security。① enabled检查browise.auth.enabled配置开关 ② excludePaths匹配/auth/ /login /captcha /error 放行支持/**前缀 ③ extractTokenAuthorization: Bearer xxx → 没有则查Cookie BROWISE_AT ④ JwtUtil.validateHS256验签 exp过期检查 ⑤ JwtBlacklist双查 isInvalid(psnId, iat) ← 用户级改密后iat之前的全失效 isInvalidByToken(token) ← token级登出单设备 ⑥ CacheManager.getUserProfile(psnId) → OP_PERSON SYS_USER.STATUS禁用即拒 ⑦ CurrentUser.set(profile) ← ThreadLocal业务代码随处可取 ⑧ MenuAuthProvider.canAccess(profile, /ea/page) → 用户角色 → SYS_ROLE_MENU → 菜单路径匹配 → 不匹配返回403 ⑨ finally CurrentUser.clear() ← ThreadLocal必须清否则线程池复用串用户第2跳EaControllerformbuilder模块browise-formbuilder/.../controller/EaController.java15.2KBPostMapping(/ea/page/{sqlId})publicResultpage(PathVariableStringsqlId,RequestBodyMapString,Objectparams){intpageNum...,pageSize...;ListMapString,ObjectrowseaEngine.query(sqlId,params,pageNum,pageSize);longtotaleaEngine.count(sqlId,params);returnResult.ok(PageResult.of(rows,total));}第3跳EaEnginemetadata模块browise-metadata/.../ea/core/engine/EaEngine.java549行内部五步① EaMetadataCache.get(sqlId) → ConcurrentHashMap查缓存 → 命中EaSqlMeta EaTableMeta[] EaFieldMeta[] EaConditionMeta[] → 未命中抛EA_NOT_FOUND启动时MetadataLoader已全量装载 ② SqlBuilder.buildSelect(sqlId, params, dialect) → appendColumns按EaFieldMeta.dataType(1字符/2日期/3数字/4日期时间) 选方言列表达式Oracle: to_char(birth,yyyymmdd) → appendFromEaTableMeta多表JOIN或主表 → where 11 → appendJoinAndWhere按EaConditionMeta拼条件 conditionType1固定值始终拼接动态参数null跳过 ③ dialect.paginate(sql, orderBy, start, end) → OracleDialectROWNUM三层包装第10篇专述 → MySqlDialectLIMIT ? OFFSET ? ④ EaConnectionProvider.getConnection() → BrowiseEaProvider从Spring DataSource取连接 → PreparedStatement参数化执行禁止字符串拼接 ⑤ postProcess(rows) → 遍历EaFieldMeta isEncrypted() → Sm4EncryptStrategy.decrypt()逐字段解密 isMasked() → maskRule(3,4)脱敏→320***********1234 → SlowSqlMonitor.check(sql, params, elapsedMs) 超阈值log.warn 可选文件追加第4跳返回Result { code:0, msg:success, data:{ rows:[...], total:137 } } → GlobalExceptionHandler兜底任何异常→Result.error(-1,msg) → 前端httpClient.ts响应拦截code!0抛业务错误401触发登出 → useRowSet灌入primary缓冲_t全为0 → MetaGrid渲染二、例二审批通过 POST /api/workflow/process/complete这条链更长穿platform→workflow→metadata三个模块① JwtAuthFilter同上 ② ProcessControllerbrowise-workflow/.../ProcessController.java28.9KB ├─ resolveFormSqlid(taskId) │ → WorkflowConfigService.findForm()查ACT_RE_BINDINGFORM │ → 拿到流程节点绑定的表单sqlId │ ├─ 表单数据upsert到T_DATA │ → FormDataMapper存在则update不存在则insert │ → 走EA引擎的insert/updateByFields │ └─ FlowableProcessService.completeTask(taskId, variables) │ ├─ ①前置拦截器 │ InterceptorChainService按TaskInterceptorConfig表 │ 读before拦截器id串从ApplicationContext取Bean执行 │ ├─ ②taskService.complete() │ → Flowable引擎推进到下一节点 │ ├─ ③后置拦截器 │ 同①after id串 │ └─ ④下一任务处理人通知 → WorkflowNotifyService发WorkflowMessageEventSpring事件 → TransactionalEventListener(AFTER_COMMIT)监听 → 事务提交后才WebSocket推送 ← 关键事务没提交就推送用户点待办却查不到数据三、两条链的公共部分环节组件位置认证JwtAuthFilter CurrentUser(ThreadLocal)platform鉴权菜单RBAC AuthAspect(RequirePermission/DataScope)platform数据EaEngine SqlBuilder Dialectmetadata异常GlobalExceptionHandler → Resultplatform上下文清理finally CurrentUser.clear() DataScope popplatform这就是16个模块在运行时的协作方式——不是所有请求都穿过所有模块而是按URL前缀路由到对应Controller公共能力认证/异常/EA数据访问横切所有链路。四、系列后续怎么展开这篇出现的每个环节后面各有一篇或几篇拆到底本篇环节后续文章EaEngine五步06篇引擎调度、07-08篇SqlBuilderDialect分页09-10篇8方言与ROWNUM演化postProcess加密脱敏14-15篇JwtAuthFilter九步25-26篇双令牌、黑名单CurrentUser29篇ThreadLocal上下文InterceptorChain41篇数据库配置的拦截器链事件推送43篇事务提交后WebSocket✅ 亮点用一查一改两条真实链路把16模块的运行时协作串起来每跳标注模块归属和源码文件——是整个系列的导航图。适合第一次接触多模块项目的人建立全局观。扩展方向后续每篇都是本文某一跳的代码级展开。
延伸阅读

更多相关文章

2026/10/17 8:56:38

Docker部署翼龙面板前端:从环境准备到生产级配置全攻略

1. 为什么选择Docker部署翼龙面板前端?如果你正在管理一个游戏服务器,或者运营一个提供多用户游戏服务器托管服务的平台,那么Pterodactyl(翼龙面板)这个名字你大概率不会陌生。它是一个开源的、功能强大的游戏服务器管…

2026/10/16 18:26:27

python的运筹学工业场景模拟第八十七篇:读取管网台账,提取每条管道最大流量,清洗废弃管道,构建网络最大流模型参数。

管网“疏通器”:用Python清洗废弃管线,给最大流模型造“干净拓扑”“某化工园区有 87 条工艺管道、12 个关键节点,每月做一次管网输配能力评估。计划员花 2 天手工整理管网台账、剔除废弃管线、核对每条管的最大流量,再手动录入最…

2026/10/17 13:13:04

推荐几家做草花靠谱的供应商

引言在园林景观、城市绿化等众多场景中,草花凭借其绚丽多彩的花色、丰富的品种以及较强的适应性,占据着重要地位。选择一家靠谱的草花供应商至关重要,它能为项目的成功提供有力保障。接下来为大家推荐几家在行业内比较靠谱的草花供应商。地邦…

2026/10/18 17:28:33

瑞吉外卖Java项目本地环境搭建完整指南

简介:本资源为「瑞吉外卖」全栈项目实战源码包,面向Java后端与前端初学者、毕业设计开发者及微服务入门学习者,提供一套功能完整、结构清晰的餐饮外卖系统参考实现。压缩包共1275个文件,涵盖147个JavaScript交互逻辑、86个Java后端…

2026/10/18 17:28:33

RSA-cyclic1026:二维颗粒建模的受控随机填充方法

简介:本资源是一份面向材料科学与仿真工程师的ABAQUS二次开发实践脚本,聚焦二维随机分布颗粒增强复合材料的自动化建模问题,适用于高校科研、企业材料性能仿真及有限元进阶学习者。核心文件为1个Python脚本(RSA-cyclic1026.py&…

2026/10/18 17:28:33

Python实现IEEE 33节点前推回代潮流计算详解

简介:面向电力系统初学者与配电网研究者,围绕IEEE33节点辐射状配电网,前推回代法潮流计算的完整示例以rar压缩包形式呈现,便于系统学习配电网潮流求解方法。前推回代法以功率从末端向电源逐级累加、电压从电源向末端逐级修正为思路…

2026/10/18 17:28:33

回调系统的可观测性落地:监控、日志与链路追踪的完整实践

"回调系统"这四个字,听起来是个老生常谈的基础话题,但把"监控、日志、链的执行过程追踪"这三件事放在一起,就变成了另一个量级的问题。这也是我在这个系列的第019篇里最想聊透的内容——大多数项目不是死在回调功能本身&…

2026/10/18 17:23:33

Cesium航线规划实战:坐标转换、轨迹生成与动态飞行全流程

简介:这是一份基于CesiumJS的无人机航线规划实现源码包,面向三维GIS和Web前端开发者,完整复刻大疆司空2的航线设计、动态渲染与交互逻辑。项目针对航线箭头渲染这一核心难点,采用离屏Canvas动态生成箭头位图,再通过Ces…

2026/10/18 0:01:50

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/18 0:01:50

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑