Spring Boot+SPA 解决刷新403时如何仅对UI路径重定向,保留/api错误处理
当前实现的核心问题
你写的自定义/error映射,直接覆盖了Spring Boot原生的错误控制器BasicErrorController——所有触发错误流程的请求(不管是前端页面路径还是/api/**接口),都会被强制走你的重定向逻辑,转发到/(index.html)。
当原始请求是发给/api/someApi的POST参数错误时,转发后的请求实际等价于“向index.html发送POST请求”,而静态资源路径默认只支持GET方法,自然就会返回405 Method Not Allowed,完全丢失了接口原本的错误状态和结构化错误信息。
可落地的实现方案
方案一:改造现有/error处理器,基于原始请求路径分流
Spring Boot在进入错误流程时,会把原始请求的关键信息存在request的内置属性中,你可以通过这些属性判断是否要触发重定向:
- 从request中读取
RequestDispatcher.ERROR_REQUEST_URI,拿到触发错误的原始请求路径 - 对
/api/前缀的请求,直接返回Spring默认的错误响应,不做转发
修正后的核心代码(顺便修正原代码中的笔误:ModelAndView拼写、@RequestMapping的路径引号缺失):
@RequestMapping("/error") public ModelAndView redirect(HttpServletRequest request) { // 读取Spring内置错误上下文的原始请求信息 String originalUri = (String) request.getAttribute(RequestDispatcher.ERROR_REQUEST_URI); Integer originalStatusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); // 接口类请求:保留原生错误处理逻辑,不重定向 if (originalUri != null && originalUri.startsWith("/api/")) { ModelAndView defaultError = new ModelAndView(); // 恢复原始错误状态码,避免状态被覆盖 defaultError.setStatus(HttpStatus.valueOf(originalStatusCode)); // 交给Spring默认的错误视图生成逻辑返回结构化错误 defaultError.setView(new MappingJackson2JsonView()); return defaultError; } // 非接口的UI路径请求:转发到index.html交给SPA路由处理 return new ModelAndView("forward:/"); }
方案二(更推荐):基于Spring Boot内置扩展点ErrorViewResolver实现分流
Spring Boot专门预留了ErrorViewResolver接口用来自定义错误视图的返回逻辑,用这个方案完全不需要覆盖原生的BasicErrorController,不会破坏原有错误处理流程:
@Component public class SpaForwardErrorViewResolver implements ErrorViewResolver { @Override public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) { String originalUri = (String) request.getAttribute(RequestDispatcher.ERROR_REQUEST_URI); // 接口路径的错误:返回null表示不做自定义处理,直接走Spring默认错误逻辑 if (originalUri != null && originalUri.startsWith("/api/")) { return null; } // UI路径的错误:转发到index.html return new ModelAndView("forward:/"); } }
这个方案的优势:
- 完全不修改Spring Boot原生的错误控制器,
/api/**的错误会完全保持原有行为:返回对应的状态码、结构化JSON错误体、全局异常处理器的逻辑也不会被打断 - 不需要手动处理状态码、错误模型的传递,Spring会自动把原有的错误上下文传给默认处理器
- 从根源上避免了转发到静态资源后触发方法不支持、状态码错乱的问题
常见踩坑提醒
- 若项目集成了Spring Security,需保证
/error路径被Security过滤器链放行,否则请求进入错误流程时会先被Security拦截,导致分流逻辑无法生效 - 路径匹配规则要严格,避免把
/api/下的路径错误转发到index,startsWith("/api/")的规则可以正常覆盖多层嵌套的api路径(比如/api/user/profile) - 静态资源路径(比如
/static/**、/assets/**)的错误可以根据需要选择是否一起转发,不影响api的分流逻辑
内容的提问来源于stack exchange,提问作者TheUnreal
相关产品推荐
相关产品推荐

