如何使用Spring拦截器实现结算页跳转管控,强制离开用户重回结算URL
功能可行性说明
完全可以通过Spring MVC拦截器实现该需求,不过需要配合会话状态标记完成逻辑判断,仅靠单请求特征无法实现精准拦截。
实现核心逻辑
- 首先在用户进入结算URL时,在当前用户的
HttpSession中存入两个字段:结算状态标记IN_SETTLEMENT_PROCESS赋值为true,同时存储当前结算页面的完整URL到SETTLEMENT_TARGET_URL字段。 - 自定义Spring拦截器实现
HandlerInterceptor接口,重写preHandle方法,执行如下判断逻辑:- 先校验当前用户session中是否存在生效的
IN_SETTLEMENT_PROCESS标记,不存在则直接放行请求 - 若处于结算流程中,判断当前请求是否属于放行范围:结算页本身、结算流程依赖的后端接口(比如地址选择、支付调用接口)、静态资源(js/css/图片等)
- 不属于放行范围的请求,直接执行重定向到存储的
SETTLEMENT_TARGET_URL即可
- 先校验当前用户session中是否存在生效的
- 结算流程结束(支付成功/用户主动取消结算)后,必须立刻清除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
相关产品推荐
相关产品推荐

