宁波品牌网站制作哪家好,网络营销方案分析整理,合肥建筑网站大全,百度seo排名优化排行文章目录 基本说明问题描述问题原因解决方法前端执行的所有请求都通过Controller#xff0c;而不是直接访问html定义一个/error路径的方法 总结 基本说明
我的前后端项目是放在一起的#xff0c;前后端都是由springMVC进行控制#xff0c;但是现在我在拦截器的preHandle方法… 文章目录 基本说明问题描述问题原因解决方法前端执行的所有请求都通过Controller而不是直接访问html定义一个/error路径的方法 总结 基本说明
我的前后端项目是放在一起的前后端都是由springMVC进行控制但是现在我在拦截器的preHandle方法中抛出的异常并没有被全局异常处理器捕获到。下面是我的项目结构 问题描述
我定义了一个拦截器并且将其注入到了spring容器 然后在全局异常处理器中对异常进行了处理 这个时候如果我没有登录就访问主页面那么程序并不会执行到handleLoginException方法而是直接去调寻找/error路径的页面 可以看见我访问的页面是http://localhost/admin/index.html当我没有登录的时候应该跳转到登录页面也就是login.html但是在拦截器的preHandle抛出异常之后并没有被全局异常处理器捕获而是再去寻找/error路径的处理器然后又被拦截-抛出异常-寻找/error处理器-拦截直接就产生了循环。
问题原因
想要分析这个问题那么就要去看springMVC源码了。
首先找到org.springframework.web.servlet.DispatcherServlet#doDispatch这个就是springMVC的核心。在这个方法里面找到执行preHandle的方法 现在已知preHandle中会抛出一个LoginException异常于是直接看catch中的代码 可以发现会将异常记录然后执行processDispatchResult方法 继续查看processHandlerException方法 这个方法里面就是遍历所有的异常解析器来解析首先看看DefaultErrorAttributes的解析器 这里就是简单的记录一下然后去查看HandlerExceptionResolverComposite 可以发现在在里面又有3个解析器来对异常进行解析需要关注的就是的一个异常解析器这个就是处理全局异常的继续往里面看 可以发现首先会对handler进行检查 可以发现这里会直接返回false也就是并不会对异常进行处理然后异常会一直往外面抛最终执行到org.apache.catalina.core.StandardHostValve#status方法然后返回一个默认/error路径 这里就有疑问了为什么在全局异常处理器不会对preHandle抛出的异常进行处理呢如下 原因就是DispathcerServlet#doDispatch中获取执行链时发现请求的是一个页面而不是Controller于是就导致了执行上面的shouldApplyTo方法时不会进行处理直接返回false。
解决方法
前端执行的所有请求都通过Controller而不是直接访问html
定义一个admin/index方法返回admin/index.html页面 这样在执行getHandler时就可以获取到执行器链 这样在preHandle中抛出的异常就可以被解析 执行异常处理器的方法 可以发现上面的异常就可以被全局异常处理器捕获了
定义一个/error路径的方法
由于默认情况下会打到error可以将默认返回的页面写到该方法中。 总结
如果前后端项目放在一起写前端项目的访问也由springMVC来控制那么当访问前端页面时如果在拦截器preHandle中抛出异常这个异常并不会被全局异常处理器所捕获而是会将该错误一直往上抛最终由org.apache.catalina.core.StandardHostValve#status方法所处理会默认去访问htpp://localhost/error接口。
是会将该错误一直往上抛最终由org.apache.catalina.core.StandardHostValve#status方法所处理会默认去访问htpp://localhost/error接口。
如果请求的是后端定义的接口那么在preHandle中抛出的异常会被全局异常处理器捕获