核心流规则与自定义异常类协同实现非法金额拦截,通过分层规则(格式/业务/风控/流量)、结构化异常快照、入口上下文预采集及异常驱动下游动作四环节闭环。

核心流规则与自定义异常类配合拦截非法金额,关键在于把“判别”“拦截”“记录”“联动”四件事串成一条可追踪、不丢现场的链路,而不是在某个 if 里 throw new Exception() 就完事。
用流规则定义分层拦截边界
非法金额不是单一条件,而是多维度组合信号。流规则要按业务语义分级,每级对应不同响应动作:
-
基础格式规则:如金额为字符串时含非法字符、小数位数超限(JPY 必须整数,USD/EUR 必须两位)、负数或零值用于支付场景 → 抛
PrecisionMismatchException -
业务逻辑规则:单笔超过账户日限额、同一订单重复提交相同金额、金额与商品价格明显偏离(如 1 元买 iPhone)→ 抛
BusinessRuleViolationException -
风控协同规则:该 account_id 近 2 分钟内触发 3 次精度校验失败,或关联设备近 1 小时有高风险交易 → 自动升级为
HighRiskAmountException -
流量防护规则:同一 IP+account_id 组合 1 秒内发起超 8 笔金额校验请求 → 不直接报错,改抛
RateLimitedAmountException,并写入 Redis 计数器
自定义异常类必须携带结构化快照
异常不是错误容器,是规则执行后的“业务快照”。每个金额异常类都应继承统一基类,并强制注入上下文数据:
- 构造时必须传入
AmountSnapshot对象,含amount_raw(原始输入字符串)、account_id、currency、trace_id、rule_ids(触发的规则 ID 列表) - 重写
getErrorCode():返回语义明确的错误码,如AMT_FORMAT_INVALID、AMT_EXCEED_DAILY_LIMIT - 提供
toAuditLog()方法:输出 JSON 化审计字段,供 ELK 实时聚合分析,例如:{"trace_id":"abc123","account_id":"U98765","raw":"100.000","currency":"USD","rule_chain":["precision","daily_limit"]}
在入口统一采集上下文,避免现场丢失
不要等规则命中后再拼数据。应在请求进入交易主流程前,就完成轻量初始化:
- 在网关或 Controller 入口调用
AmountFlowContext.begin(accountId, rawAmount, currency) - 该方法自动记录毫秒级时间戳、生成 trace_id、预加载账户基础属性(如默认币种、风控等级、白名单标识)
- 后续所有规则校验、异常抛出,均复用此上下文 —— 即使校验嵌套在资金冻结、汇率换算、优惠抵扣等多层 service 中,快照始终是“事发当时”的那一份
拦截后必须驱动真实下游动作
抛出异常只是起点,闭环在于让异常变成可操作信号:
- 全局异常处理器捕获
HighRiskAmountException后,自动调用风控服务发起临时冻结,并标记该 account_id 进入观察期 - 捕获
RateLimitedAmountException时,向 Redis 写入rate:acct:{id}并设 TTL=60s,同时返回 HTTP 429 + Retry-After 头 - 所有异常日志通过 Logback 的
%X{amount_snapshot}输出结构化字段,确保每条日志天然带上下文,无需额外查库补全 - 异步将异常快照写入专用审计表,字段包括
order_id(若已生成)、error_code、snapshot_json、created_at,支撑事后归因与模型训练











