You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Spring拦截器实现结算页跳转管控,强制离开用户重回结算URL

功能可行性说明

完全可以通过Spring MVC拦截器实现该需求,不过需要配合会话状态标记完成逻辑判断,仅靠单请求特征无法实现精准拦截。

实现核心逻辑
  • 首先在用户进入结算URL时,在当前用户的HttpSession中存入两个字段:结算状态标记IN_SETTLEMENT_PROCESS赋值为true,同时存储当前结算页面的完整URL到SETTLEMENT_TARGET_URL字段。
  • 自定义Spring拦截器实现HandlerInterceptor接口,重写preHandle方法,执行如下判断逻辑:
    1. 先校验当前用户session中是否存在生效的IN_SETTLEMENT_PROCESS标记,不存在则直接放行请求
    2. 若处于结算流程中,判断当前请求是否属于放行范围:结算页本身、结算流程依赖的后端接口(比如地址选择、支付调用接口)、静态资源(js/css/图片等)
    3. 不属于放行范围的请求,直接执行重定向到存储的SETTLEMENT_TARGET_URL即可
  • 结算流程结束(支付成功/用户主动取消结算)后,必须立刻清除session中的两个标记字段,避免影响用户后续正常访问。
注意事项
  • 一定要梳理清楚结算页依赖的所有资源/接口,全部加入放行名单,否则会导致结算页本身功能异常
  • Spring拦截器仅能处理发送到当前服务端的请求,如果用户手动在地址栏输入第三方外部站点URL,该请求不会进入你的后端服务,这种场景需要配合前端beforeunload事件做二次确认,和后端拦截器形成双保险
  • 注意session的有效期,避免用户停留在结算页过久session失效导致拦截逻辑异常。
核心代码示例

自定义拦截器实现:

@Component
public class SettlementInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
        Boolean inSettlement = (Boolean) session.getAttribute("IN_SETTLEMENT_PROCESS");
        String settlementUrl = (String) session.getAttribute("SETTLEMENT_TARGET_URL");
        
        // 不在结算流程直接放行
        if (inSettlement == null || !inSettlement || settlementUrl == null) {
            return true;
        }
        
        String requestUri = request.getRequestURI();
        // 放行结算页、结算相关接口、静态资源
        if (requestUri.startsWith(settlementUrl) || requestUri.startsWith("/api/settlement/") || requestUri.startsWith("/static/")) {
            return true;
        }
        
        // 其余请求重定向回结算页
        response.sendRedirect(settlementUrl);
        return false;
    }
}

拦截器注册配置:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private SettlementInterceptor settlementInterceptor;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(settlementInterceptor)
                .addPathPatterns("/**") // 拦截全量请求
                .excludePathPatterns("/login", "/logout"); // 排除登录登出这类必须放行的全局路径
    }
}

结算页入口打标记逻辑:

@GetMapping("/settlement")
public String settlementPage(HttpSession session) {
    session.setAttribute("IN_SETTLEMENT_PROCESS", true);
    session.setAttribute("SETTLEMENT_TARGET_URL", "/settlement");
    return "settlement";
}

内容的提问来源于stack exchange,提问作者Nexussim Lements

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 22:15:05